# <small>nlohmann::basic_json::</small>basic_json

```cpp
// (1)
basic_json(const value_t v);

// (2)
basic_json(std::nullptr_t = nullptr) noexcept;

// (3)
template<typename CompatibleType>
basic_json(CompatibleType&& val) noexcept(noexcept(
           JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
                                      std::forward<CompatibleType>(val))));

// (4)
template<typename BasicJsonType>
basic_json(const BasicJsonType& val);

// (5)
basic_json(initializer_list_t init,
           bool type_deduction = true,
           value_t manual_type = value_t::array);

// (6)
basic_json(size_type cnt, const basic_json& val);

// (7)
basic_json(iterator first, iterator last);
basic_json(const_iterator first, const_iterator last);

// (8)
basic_json(const basic_json& other);

// (9)
basic_json(basic_json&& other) noexcept;
```

1. Create an empty JSON value with a given type. The value will be default initialized with an empty value which depends
   on the type:

    | Value type | initial value  |
    |------------|----------------|
    | null       | `#!json null`  |
    | boolean    | `#!json false` |
    | string     | `#!json ""`    |
    | number     | `#!json 0`     |
    | object     | `#!json {}`    |
    | array      | `#!json []`    |
    | binary     | empty array    |

    The postcondition of this constructor can be restored by calling [`clear()`](clear.md).

2. Create a `#!json null` JSON value. It either takes a null pointer as parameter (explicitly creating `#!json null`)
   or no parameter (implicitly creating `#!json null`). The passed null pointer itself is not read -- it is only used to
   choose the right constructor.

3. This is a "catch all" constructor for all compatible JSON types; that is, types for which a `to_json()` method
   exists. The constructor forwards the parameter `val` to that method (to `json_serializer<U>::to_json` method with
   `U = uncvref_t<CompatibleType>`, to be exact).

    Template type `CompatibleType` includes, but is not limited to, the following types:

    - **arrays**: [`array_t`](array_t.md) and all kinds of compatible containers such as `std::vector`, `std::deque`,
     `std::list`, `std::forward_list`, `std::array`, `std::valarray`, `std::set`, `std::unordered_set`, `std::multiset`,
     and `std::unordered_multiset` with a `value_type` from which a `basic_json` value can be constructed.
    - **objects**: [`object_t`](object_t.md) and all kinds of compatible associative containers such as `std::map`,
     `std::unordered_map`, `std::multimap`, and `std::unordered_multimap` with a `key_type` compatible to `string_t`
     and a `value_type` from which a `basic_json` value can be constructed.
    - **strings**: `string_t`, string literals, and all compatible string containers can be used.
    - **numbers**: [`number_integer_t`](number_integer_t.md), [`number_unsigned_t`](number_unsigned_t.md),
     [`number_float_t`](number_float_t.md), and all convertible number types such as `int`, `size_t`, `int64_t`, `float`
     or `double` can be used.
    - **boolean**: `boolean_t` / `bool` can be used.
    - **binary**: `binary_t` / `std::vector<uint8_t>` may be used; unfortunately because string literals cannot be
     distinguished from binary character arrays by the C++ type system, all types compatible with `const char*` will be
     directed to the string constructor instead. This is both for backwards compatibility and due to the fact that a
     binary type is not a standard JSON type.

    See the examples below.

4. This is a constructor for existing `basic_json` types. It does not hijack copy/move constructors, since the parameter
   has different template arguments than the current ones.

    The constructor tries to convert the internal `m_value` of the parameter. Each member value (object, array, string,
    etc.) is serialized via the corresponding `to_json()` overload. For objects and strings, the conversion requires
    that the *target* `basic_json` type's `object_t::key_type` (or `string_t`) be directly constructible from the
    *source* type's corresponding member type via `is_constructible`. If this requirement is not met, the conversion
    does not fail to compile; instead, it silently falls back to the array-conversion path, which represents objects
    as arrays of `[key, value]` pairs and strings as arrays of character codes. This is a known limitation tracked in
    [issue #3425](https://github.com/nlohmann/json/issues/3425).

5. Creates a JSON value of type array or object from the passed initializer list `init`. In case `type_deduction` is
   `#!cpp true` (default), the type of the JSON value to be created is deducted from the initializer list `init`
   according to the following rules:

    1. If the list is empty, an empty JSON object value `{}` is created.
    2. If the list consists of pairs whose first element is a string, a JSON object value is created where the first
      elements of the pairs are treated as keys and the second elements are as values.
    3. In all other cases, an array is created.

    The rules aim to create the best fit between a C++ initializer list and JSON values. The rationale is as follows:

    1. The empty initializer list is written as `#!cpp {}` which is exactly an empty JSON object.
    2. C++ has no way of describing mapped types other than to list a list of pairs. As JSON requires that keys must be
       of type string, rule 2 is the weakest constraint one can pose on initializer lists to interpret them as an
       object.
    3. In all other cases, the initializer list could not be interpreted as a JSON object type, so interpreting it as a
       JSON array type is safe.

    With the rules described above, the following JSON values cannot be expressed by an initializer list:

    - the empty array (`#!json []`): use `array(initializer_list_t)` with an empty initializer list in this case
    - arrays whose elements satisfy rule 2: use `array(initializer_list_t)` with the same initializer list in this case

    Function [`array()`](array.md) and [`object()`](object.md) force array and object creation from initializer lists,
    respectively.

    !!! warning "Brace initialization yields arrays"

        Because this constructor takes an `initializer_list_t`, brace-initializing a `json`/`ordered_json` from
        another `json` value wraps it in a single-element array rather than copying it:

        ```cpp
        json j1 = "hello";
        json j2{j1};   // [!] j2 is ["hello"], NOT a copy of j1
        json j3(j1);   // j3 is "hello" -- parentheses copy as expected
        ```

        See the FAQ entry on [brace initialization](../../home/faq.md#brace-initialization-yields-arrays) for the
        full explanation, an opt-in macro to change this behavior, and how to explicitly create a single-element
        array (`json::array({value})`) if that is what you want.

6. Constructs a JSON array value by creating `cnt` copies of a passed value. In case `cnt` is `0`, an empty array is
   created.

7. Constructs the JSON value with the contents of the range `[first, last)`. The semantics depend on the different
   types a JSON value can have:

    - In case of a `#!json null` type, [invalid_iterator.206](../../home/exceptions.md#jsonexceptioninvalid_iterator206)
      is thrown.
    - In case of other primitive types (number, boolean, or string), `first` must be `begin()` and `last` must be
      `end()`. In this case, the value is copied. Otherwise,
      [`invalid_iterator.204`](../../home/exceptions.md#jsonexceptioninvalid_iterator204) is thrown.
    - In case of structured types (array, object), the constructor behaves as similar versions for `std::vector` or
      `std::map`; that is, a JSON array or object is constructed from the values in the range.

8. Creates a copy of a given JSON value.

9. Move constructor. Constructs a JSON value with the contents of the given value `other` using move semantics. It
   "steals" the resources from `other` and leaves it as JSON `#!json null` value.

## Template parameters

`CompatibleType`
:   a type such that:

    - `CompatibleType` is not derived from `std::istream`,
    - `CompatibleType` is not `basic_json` (to avoid hijacking copy/move constructors),
    - `CompatibleType` is not a different `basic_json` type (i.e. with different template arguments)
    - `CompatibleType` is not a `basic_json` nested type (e.g., `json_pointer`, `iterator`, etc.)
    - `json_serializer<U>` (with `U = uncvref_t<CompatibleType>`) has a `to_json(basic_json_t&, CompatibleType&&)`
       method

`BasicJsonType`:
:   a type such that:

    - `BasicJsonType` is a `basic_json` type.
    - `BasicJsonType` has different template arguments than `basic_json_t`.

    **Note:** For cross-`basic_json` conversions to produce correct results, the target `basic_json`'s
    `object_t::key_type` and `string_t` must be directly constructible from the source `basic_json`'s
    corresponding types. See the description of overload (4) above for details on what happens when
    this requirement is not met.

`U`:
:   `uncvref_t<CompatibleType>`

## Parameters

`v` (in)
:   the type of the value to create

`val` (in)
:   the value to be forwarded to the respective constructor

`init` (in)
:   initializer list with JSON values

`type_deduction` (in)
:   internal parameter; when set to `#!cpp true`, the type of the JSON value is deducted from the initializer list
    `init`; when set to `#!cpp false`, the type provided via `manual_type` is forced. This mode is used by the functions
    `array(initializer_list_t)` and `object(initializer_list_t)`.

`manual_type` (in)
:   internal parameter; when `type_deduction` is set to `#!cpp false`, the created JSON value will use the provided type
    (only `value_t::array` and `value_t::object` are valid); when `type_deduction` is set to `#!cpp true`, this
    parameter has no effect

`cnt` (in)
:   the number of JSON copies of `val` to create

`first` (in)
:   the beginning of the range to copy from (included)

`last` (in)
:   the end of the range to copy from (excluded)

`other` (in)
:   the JSON value to copy/move

## Exception safety

1. Strong guarantee: if an exception is thrown, there are no changes to any JSON value.
2. No-throw guarantee: this constructor never throws exceptions.
3. Depends on the called constructor. For types directly supported by the library (i.e., all types for which no
   `to_json()` function was provided), a strong guarantee holds: if an exception is thrown, there are no changes to any
   JSON value.
4. Depends on the called constructor. For types directly supported by the library (i.e., all types for which no
   `to_json()` function was provided), a strong guarantee holds: if an exception is thrown, there are no changes to any
   JSON value.
5. Strong guarantee: if an exception is thrown, there are no changes to any JSON value.
6. Strong guarantee: if an exception is thrown, there are no changes to any JSON value.
7. Strong guarantee: if an exception is thrown, there are no changes to any JSON value.
8. Strong guarantee: if an exception is thrown, there are no changes to any JSON value.
9. No-throw guarantee: this constructor never throws exceptions.

## Exceptions

1. (none)
2. The function does not throw exceptions.
3. (none)
4. (none)
5. The function can throw the following exceptions:
    - Throws [`type_error.301`](../../home/exceptions.md#jsonexceptiontype_error301) if `type_deduction` is
      `#!cpp false`, `manual_type` is `value_t::object`, but `init` contains an element which is not a pair whose first
      element is a string. In this case, the constructor could not create an object. If `type_deduction` would have been
      `#!cpp true`, an array would have been created. See `object(initializer_list_t)` for an example.
6. (none)
7. The function can throw the following exceptions:
    - Throws [`invalid_iterator.201`](../../home/exceptions.md#jsonexceptioninvalid_iterator201) if iterators `first`
      and `last` are not compatible (i.e., do not belong to the same JSON value). In this case, the range
      `[first, last)` is undefined.
    - Throws [`invalid_iterator.204`](../../home/exceptions.md#jsonexceptioninvalid_iterator204) if iterators `first`
      and `last` belong to a primitive type (number, boolean, or string), but `first` does not point to the first
      element anymore. In this case, the range `[first, last)` is undefined. See the example code below.
    - Throws [`invalid_iterator.206`](../../home/exceptions.md#jsonexceptioninvalid_iterator206) if iterators `first`
      and `last` belong to a `#!json null` value. In this case, the range `[first, last)` is undefined.
8. (none)
9. The function does not throw exceptions.

## Complexity

1. Constant.
2. Constant.
3. Usually linear in the size of the passed `val`, also depending on the implementation of the called `to_json()`
   method.
4. Usually linear in the size of the passed `val`, also depending on the implementation of the called `to_json()`
   method.
5. Linear in the size of the initializer list `init`.
6. Linear in `cnt`.
7. Linear in distance between `first` and `last`.
8. Linear in the size of `other`.
9. Constant.

## Notes

- Overload 5:

    !!! note "Empty initializer list"

        When used without parentheses around an empty initializer list, `basic_json()` is called instead of this
        function, yielding the JSON `#!json null` value.

- Overload 7:

    !!! info "Preconditions"

        - Iterators `first` and `last` must be initialized. **This precondition is enforced with a
          [runtime assertion](../../features/assertions.md).
        - Range `[first, last)` is valid. Usually, this precondition cannot be checked efficiently. Only certain edge
          cases are detected; see the description of the exceptions above. A violation of this precondition yields
          undefined behavior.

    !!! danger "Runtime assertion"

        A precondition is enforced with a [runtime assertion](../../features/assertions.md).

- Overload 8:

    !!! info "Postcondition"

        `#!cpp *this == other`

- Overload 9:

    !!! info "Postconditions"

        - `#!cpp `*this` has the same value as `other` before the call.
        - `other` is a JSON `#!json null` value

## Examples

??? example "Example: (1) create an empty value with a given type"

    The following code shows the constructor for different `value_t` values.

    ```cpp
    --8<-- "examples/basic_json__value_t.cpp"
    ```

    Output:

    ```json
    --8<-- "examples/basic_json__value_t.output"
    ```

??? example "Example: (2) create a `#!json null` object"

    The following code shows the constructor with and without a null pointer parameter.

    ```cpp
    --8<-- "examples/basic_json__nullptr_t.cpp"
    ```

    Output:

    ```json
    --8<-- "examples/basic_json__nullptr_t.output"
    ```

??? example "Example: (3) create a JSON value from compatible types"

    The following code shows the constructor with several compatible types.

    ```cpp
    --8<-- "examples/basic_json__CompatibleType.cpp"
    ```

    Output:

    ```json
    --8<-- "examples/basic_json__CompatibleType.output"
    ```

    Note the output is platform-dependent.

??? example "Example: (5) create a container (array or object) from an initializer list"

    The example below shows how JSON values are created from initializer lists.

    ```cpp
    --8<-- "examples/basic_json__list_init_t.cpp"
    ```

    Output:

    ```json
    --8<-- "examples/basic_json__list_init_t.output"
    ```

??? example "Example: (6) construct an array with count copies of a given value"

    The following code shows examples for creating arrays with several copies of a given value.

    ```cpp
    --8<-- "examples/basic_json__size_type_basic_json.cpp"
    ```

    Output:

    ```json
    --8<-- "examples/basic_json__size_type_basic_json.output"
    ```

??? example "Example: (7) construct a JSON container given an iterator range"

    The example below shows several ways to create JSON values by specifying a subrange with iterators.

    ```cpp
    --8<-- "examples/basic_json__InputIt_InputIt.cpp"
    ```

    Output:

    ```json
    --8<-- "examples/basic_json__InputIt_InputIt.output"
    ```

??? example "Example: (8) copy constructor"

    The following code shows an example for the copy constructor.

    ```cpp
    --8<-- "examples/basic_json__basic_json.cpp"
    ```

    Output:

    ```json
    --8<-- "examples/basic_json__basic_json.output"
    ```

??? example "Example: (9) move constructor"

    The code below shows the move constructor explicitly called via `std::move`.

    ```cpp
    --8<-- "examples/basic_json__moveconstructor.cpp"
    ```

    Output:

    ```json
    --8<-- "examples/basic_json__moveconstructor.output"
    ```

## Version history

1. Since version 1.0.0.
2. Since version 1.0.0.
3. Since version 2.1.0.
4. Since version 3.2.0.
5. Since version 1.0.0.
6. Since version 1.0.0.
7. Since version 1.0.0.
8. Since version 1.0.0.
9. Since version 1.0.0.


import path from 'node:path'
import type { InternalResolveOptions } from './plugins/resolve'
import { tryNodeResolve } from './plugins/resolve'
import {
  bareImportRE,
  createDebugger,
  createFilter,
  getNpmPackageName,
  isBuiltin,
  isInNodeModules,
} from './utils'
import type { Environment } from './environment'
import type { PartialEnvironment } from './baseEnvironment'

const debug = createDebugger('vite:external')

const isExternalCache = new WeakMap<
  Environment,
  (id: string, importer?: string) => boolean
>()

export function shouldExternalize(
  environment: Environment,
  id: string,
  importer: string | undefined,
): boolean {
  let isExternal = isExternalCache.get(environment)
  if (!isExternal) {
    isExternal = createIsExternal(environment)
    isExternalCache.set(environment, isExternal)
  }
  return isExternal(id, importer)
}

export function createIsConfiguredAsExternal(
  environment: PartialEnvironment,
): (id: string, importer?: string) => boolean {
  const { config } = environment
  const { root, resolve } = config
  const { external, noExternal } = resolve
  const noExternalFilter =
    typeof noExternal !== 'boolean' &&
    !(Array.isArray(noExternal) && noExternal.length === 0) &&
    createFilter(undefined, noExternal, { resolve: false })

  const targetConditions = resolve.externalConditions

  const resolveOptions: InternalResolveOptions = {
    ...resolve,
    root,
    isProduction: false,
    isBuild: true,
    conditions: targetConditions,
  }

  const isExternalizable = (
    id: string,
    importer: string | undefined,
    configuredAsExternal: boolean,
  ): boolean => {
    if (!bareImportRE.test(id) || id.includes('\0')) {
      return false
    }
    try {
      const resolved = tryNodeResolve(
        id,
        // Skip passing importer in build to avoid externalizing non-hoisted dependencies
        // unresolvable from root (which would be unresolvable from output bundles also)
        config.command === 'build' ? undefined : importer,
        resolveOptions,
        undefined,
        false,
      )
      if (!resolved) {
        return false
      }
      // Only allow linked packages to be externalized
      // if they are explicitly configured as external
      if (!configuredAsExternal && !isInNodeModules(resolved.id)) {
        return false
      }
      return canExternalizeFile(resolved.id)
    } catch {
      debug?.(
        `Failed to node resolve "${id}". Skipping externalizing it by default.`,
      )
      // may be an invalid import that's resolved by a plugin
      return false
    }
  }

  // Returns true if it is configured as external, false if it is filtered
  // by noExternal and undefined if it isn't affected by the explicit config
  return (id: string, importer?: string) => {
    if (
      // If this id is defined as external, force it as external
      // Note that individual package entries are allowed in `external`
      external !== true &&
      external.includes(id)
    ) {
      return true
    }
    const pkgName = getNpmPackageName(id)
    if (!pkgName) {
      return isExternalizable(id, importer, false)
    }
    if (
      // A package name in ssr.external externalizes every
      // externalizable package entry
      external !== true &&
      external.includes(pkgName)
    ) {
      return isExternalizable(id, importer, true)
    }
    if (typeof noExternal === 'boolean') {
      return !noExternal
    }
    if (noExternalFilter && !noExternalFilter(pkgName)) {
      return false
    }
    // If external is true, all will be externalized by default, regardless if
    // it's a linked package
    return isExternalizable(id, importer, external === true)
  }
}

function createIsExternal(
  environment: Environment,
): (id: string, importer?: string) => boolean {
  const processedIds = new Map<string, boolean>()

  const isConfiguredAsExternal = createIsConfiguredAsExternal(environment)

  return (id: string, importer?: string) => {
    if (processedIds.has(id)) {
      return processedIds.get(id)!
    }
    let isExternal = false
    if (id[0] !== '.' && !path.isAbsolute(id)) {
      isExternal =
        isBuiltin(environment.config.resolve.builtins, id) ||
        isConfiguredAsExternal(id, importer)
    }
    processedIds.set(id, isExternal)
    return isExternal
  }
}

export function canExternalizeFile(filePath: string): boolean {
  const ext = path.extname(filePath)
  // only external js imports
  return !ext || ext === '.js' || ext === '.mjs' || ext === '.cjs'
}


<link rel="stylesheet" href="./linked.css" />
<link rel="stylesheet" href="./linked-with-import.css" />

CSS Sourcemap

<inline>

<linked>: no import

<linked>: with import

<imported>: no import

<imported>: with import

<imported sass>

<imported sass> with module

<imported less> with string additionalData

<imported stylus>

<imported sugarss>

<input source-map>


import { createSignal } from 'solid-js'
import solidLogo from './assets/solid.svg'
import viteLogo from './assets/vite.svg'
import heroImg from './assets/hero.png'
import './App.css'

function App() {
  const [count, setCount] = createSignal(0)

  return (
    <>

Get started

            Edit src/App.jsx and save to test HMR

        <button
          type="button"
          class="counter"
          onClick={() => setCount((count) => count + 1)}
        >
          Count is {count()}
        </button>

          <svg class="icon" role="presentation" aria-hidden="true">
            <use href="/icons.svg#documentation-icon"></use>
          </svg>

Documentation

Your questions, answered

                Explore Vite

                Learn more

          <svg class="icon" role="presentation" aria-hidden="true">
            <use href="/icons.svg#social-icon"></use>
          </svg>

Connect with us

Join the Vite community

                <svg class="button-icon" role="presentation" aria-hidden="true">
                  <use href="/icons.svg#github-icon"></use>
                </svg>
                GitHub

                <svg class="button-icon" role="presentation" aria-hidden="true">
                  <use href="/icons.svg#discord-icon"></use>
                </svg>
                Discord

                <svg class="button-icon" role="presentation" aria-hidden="true">
                  <use href="/icons.svg#x-icon"></use>
                </svg>
                X.com

                <svg class="button-icon" role="presentation" aria-hidden="true">
                  <use href="/icons.svg#bluesky-icon"></use>
                </svg>
                Bluesky

    </>
  )
}

export default App


from __future__ import annotations

import typing as t
from contextvars import ContextVar

from werkzeug.local import LocalProxy

if t.TYPE_CHECKING:  # pragma: no cover
    from .app import Flask
    from .ctx import _AppCtxGlobals
    from .ctx import AppContext
    from .sessions import SessionMixin
    from .wrappers import Request

    T = t.TypeVar("T", covariant=True)

    class ProxyMixin(t.Protocol[T]):
        def _get_current_object(self) -> T: ...

    # These subclasses inform type checkers that the proxy objects look like the
    # proxied type along with the _get_current_object method.
    class FlaskProxy(ProxyMixin[Flask], Flask): ...

    class AppContextProxy(ProxyMixin[AppContext], AppContext): ...

    class _AppCtxGlobalsProxy(ProxyMixin[_AppCtxGlobals], _AppCtxGlobals): ...

    class RequestProxy(ProxyMixin[Request], Request): ...

    class SessionMixinProxy(ProxyMixin[SessionMixin], SessionMixin): ...

_no_app_msg = """\
Working outside of application context.

Attempted to use functionality that expected a current application to be set. To
solve this, set up an app context using 'with app.app_context()'. See the
documentation on app context for more information.\
"""
_cv_app: ContextVar[AppContext] = ContextVar("flask.app_ctx")
app_ctx: AppContextProxy = LocalProxy(  # type: ignore[assignment]
    _cv_app, unbound_message=_no_app_msg
)
current_app: FlaskProxy = LocalProxy(  # type: ignore[assignment]
    _cv_app, "app", unbound_message=_no_app_msg
)
g: _AppCtxGlobalsProxy = LocalProxy(  # type: ignore[assignment]
    _cv_app, "g", unbound_message=_no_app_msg
)

_no_req_msg = """\
Working outside of request context.

Attempted to use functionality that expected an active HTTP request. See the
documentation on request context for more information.\
"""
request: RequestProxy = LocalProxy(  # type: ignore[assignment]
    _cv_app, "request", unbound_message=_no_req_msg
)
session: SessionMixinProxy = LocalProxy(  # type: ignore[assignment]
    _cv_app, "session", unbound_message=_no_req_msg
)

def __getattr__(name: str) -> t.Any:
    import warnings

    if name == "request_ctx":
        warnings.warn(
            "'request_ctx' has merged with 'app_ctx', and will be removed"
            " in Flask 4.0. Use 'app_ctx' instead.",
            DeprecationWarning,
            stacklevel=2,
        )
        return app_ctx

    raise AttributeError(name)


export const core = [
  {
    avatar: 'https://www.github.com/yyx990803.png',
    name: 'Evan You',
    title: 'Creator',
    org: 'Vue.js',
    orgLink: 'https://vuejs.org/',
    desc: 'Creator of Vue.js and Vite.',
    links: [
      { icon: 'github', link: 'https://github.com/yyx990803' },
      { icon: 'x', link: 'https://x.com/evanyou' },
      { icon: 'bluesky', link: 'https://bsky.app/profile/evanyou.me' },
    ],
    sponsor: 'https://github.com/sponsors/yyx990803',
  },
  {
    avatar: 'https://github.com/sapphi-red.png',
    name: 'sapphi-red',
    title: 'Web Developer',
    org: 'VoidZero',
    orgLink: 'https://voidzero.dev/',
    desc: 'Vite core team member. Call me sapphi or midori ;)',
    links: [
      { icon: 'github', link: 'https://github.com/sapphi-red' },
      { icon: 'bluesky', link: 'https://bsky.app/profile/sapphi.red' },
      { icon: 'twitter', link: 'https://twitter.com/sapphi_red' },
      { icon: 'mastodon', link: 'https://elk.zone/m.webtoo.ls/@sapphi_red' },
    ],
    sponsor: 'https://github.com/sponsors/sapphi-red',
  },
  {
    avatar: 'https://www.github.com/patak-cat.png',
    name: 'Patak',
    title: 'Open Source Adventurer',
    desc: 'Core team Vite, Vitest, Elk. Steward npmx.',
    links: [
      { icon: 'github', link: 'https://github.com/patak-cat' },
      { icon: 'bluesky', link: 'https://bsky.app/profile/patak.cat' },
    ],
    sponsor: 'https://github.com/sponsors/patak-cat',
  },
  {
    avatar: 'https://www.github.com/antfu.png',
    name: 'Anthony Fu',
    title: 'A fanatical open sourceror',
    org: 'Vercel',
    orgLink: 'https://vercel.com/',
    desc: 'Core team member of Vite & Vue. Working on Nuxt.',
    links: [
      { icon: 'github', link: 'https://github.com/antfu' },
      { icon: 'bluesky', link: 'https://bsky.app/profile/antfu.me' },
      { icon: 'mastodon', link: 'https://elk.zone/m.webtoo.ls/@antfu' },
    ],
    sponsor: 'https://github.com/sponsors/antfu',
  },
  {
    avatar: 'https://github.com/bluwy.png',
    name: 'Bjorn Lu',
    title: 'Open Source Developer',
    desc: 'Building tools for fun.',
    links: [
      { icon: 'github', link: 'https://github.com/bluwy' },
      { icon: 'bluesky', link: 'https://bsky.app/profile/bluwy.me' },
      { icon: 'twitter', link: 'https://twitter.com/bluwyoo' },
      { icon: 'mastodon', link: 'https://elk.zone/m.webtoo.ls/@bluwy' },
    ],
    sponsor: 'https://bjornlu.com/sponsor',
  },
  {
    avatar: 'https://github.com/ArnaudBarre.png',
    name: 'Arnaud Barré',
    title: 'Frontend Developer',
    desc: 'Passionate about tooling around TypeScript and React.',
    links: [
      { icon: 'github', link: 'https://github.com/ArnaudBarre' },
      {
        icon: 'bluesky',
        link: 'https://bsky.app/profile/arnaud-barre.bsky.social',
      },
      { icon: 'mastodon', link: 'https://elk.zone/m.webtoo.ls/@ArnaudBarre' },
    ],
    sponsor: 'https://github.com/sponsors/ArnaudBarre',
  },
  {
    avatar: 'https://github.com/sheremet-va.png',
    name: 'Vladimir',
    title: 'Core team member of Vitest & Vite',
    org: 'VoidZero',
    orgLink: 'https://voidzero.dev/',
    desc: 'An open source fullstack developer',
    links: [
      { icon: 'github', link: 'https://github.com/sheremet-va' },
      { icon: 'bluesky', link: 'https://bsky.app/profile/erus.dev' },
      { icon: 'mastodon', link: 'https://elk.zone/m.webtoo.ls/@sheremet_va' },
    ],
    sponsor: 'https://github.com/sponsors/sheremet-va',
  },
  {
    avatar: 'https://github.com/hi-ogawa.png',
    name: 'Hiroshi Ogawa',
    title: 'Team Member of Vitest & Vite',
    org: 'VoidZero',
    orgLink: 'https://voidzero.dev/',
    desc: 'Open source enthusiast',
    links: [
      { icon: 'github', link: 'https://github.com/hi-ogawa' },
      { icon: 'bluesky', link: 'https://bsky.app/profile/hiogawa.bsky.social' },
    ],
    sponsor: 'https://github.com/sponsors/hi-ogawa',
  },
  {
    avatar: 'https://github.com/btea.png',
    name: 'btea',
    title: 'Web Developer',
    links: [{ icon: 'github', link: 'https://github.com/btea' }],
  },
]

export const advisors = [
  {
    avatar: 'https://github.com/serhalp.png',
    name: 'Philippe Serhal',
    title: 'Staff Software Engineer',
    org: 'Netlify',
    orgLink: 'https://www.netlify.com/',
    desc: 'Juggling all the frameworks at Netlify',
    links: [
      { icon: 'github', link: 'https://github.com/serhalp' },
      { icon: 'bluesky', link: 'https://bsky.app/profile/philippeserhal.com' },
    ],
  },
  {
    avatar: 'https://github.com/jamesopstad.png',
    name: 'James Opstad',
    title: 'Senior Engineer',
    org: 'Cloudflare',
    orgLink: 'https://www.cloudflare.com/',
    desc: 'Building developer tools at Cloudflare',
    links: [{ icon: 'github', link: 'https://github.com/jamesopstad' }],
  },
  {
    avatar: 'https://github.com/danielroe.png',
    name: 'Daniel Roe',
    title: 'Open Source Maintainer',
    org: 'Vercel',
    orgLink: 'https://vercel.com/',
    desc: 'Leading the Nuxt team',
    links: [
      { icon: 'github', link: 'https://github.com/danielroe' },
      { icon: 'bluesky', link: 'https://bsky.app/profile/danielroe.dev' },
    ],
    sponsor: 'https://github.com/sponsors/danielroe',
  },
]

export const emeriti = [
  {
    avatar: 'https://i.imgur.com/KMed6rQ.jpeg',
    name: 'Alec Larson',
    title: 'Entrepreneur',
    desc: 'Dabbling in social ecommerce, meta frameworks, and board games',
    links: [
      { icon: 'github', link: 'https://github.com/aleclarson' },
      { icon: 'x', link: 'https://x.com/retropragma' },
      {
        icon: 'bluesky',
        link: 'https://bsky.app/profile/retropragma.bsky.social',
      },
    ],
  },
  {
    avatar: 'https://github.com/poyoho.png',
    name: 'yoho',
    title: 'Frontend Developer',
    desc: 'Frontend. Vite team member.',
    links: [
      { icon: 'github', link: 'https://github.com/poyoho' },
      { icon: 'x', link: 'https://x.com/yoho_po' },
    ],
  },
  {
    avatar: 'https://github.com/ygj6.png',
    name: 'ygj6',
    title: 'Developer',
    desc: 'Web Developer. Vue & Vite team member',
    links: [
      { icon: 'github', link: 'https://github.com/ygj6' },
      { icon: 'x', link: 'https://x.com/ygj_66' },
    ],
  },
  {
    avatar: 'https://github.com/Niputi.png',
    name: 'Niputi',
    title: 'Developer',
    org: 'Computershare Denmark',
    desc: 'weeb/JavaScript lover.',
    links: [
      { icon: 'github', link: 'https://github.com/Niputi' },
      { icon: 'x', link: 'https://x.com/Niputi_' },
      { icon: 'bluesky', link: 'https://bsky.app/profile/niputi.bsky.social' },
    ],
  },
  {
    avatar: 'https://github.com/underfin.png',
    name: 'underfin',
    title: 'Developer',
    links: [{ icon: 'github', link: 'https://github.com/underfin' }],
  },
  {
    avatar: 'https://github.com/GrygrFlzr.png',
    name: 'GrygrFlzr',
    title: 'Developer',
    links: [
      { icon: 'github', link: 'https://github.com/GrygrFlzr' },
      { icon: 'bluesky', link: 'https://bsky.app/profile/bsky.cybeast.dev' },
    ],
  },
  {
    avatar: 'https://github.com/nihalgonsalves.png',
    name: 'Nihal Gonsalves',
    title: 'Senior Software Engineer',
    links: [{ icon: 'github', link: 'https://github.com/nihalgonsalves' }],
  },
  {
    avatar: 'https://github.com/Shinigami92.png',
    name: 'Shinigami',
    title: 'Senior Frontend Engineer',
    org: 'Faker',
    orgLink: 'https://fakerjs.dev',
    desc: 'Passionate TypeScript enthusiast working extensively with Vue SPA.',
    links: [
      { icon: 'github', link: 'https://github.com/Shinigami92' },
      { icon: 'mastodon', link: 'https://elk.zone/mas.to/@Shini92' },
    ],
  },
  {
    avatar: 'https://github.com/haoqunjiang.png',
    name: 'Haoqun Jiang',
    title: 'Core Team Member',
    org: 'Vue.js',
    orgLink: 'https://vuejs.org/',
    desc: 'Curator of best practices for Vue.js tooling',
    links: [
      { icon: 'github', link: 'https://github.com/haoqunjiang' },
      { icon: 'bluesky', link: 'https://bsky.app/profile/haoqun.dev' },
      { icon: 'mastodon', link: 'https://elk.zone/m.webtoo.ls/@haoqun' },
    ],
    sponsor: 'https://github.com/sponsors/haoqunjiang',
  },
  {
    avatar: 'https://github.com/dominikg.png',
    name: 'Dominik G.',
    title: 'Resident CI Expert',
    desc: 'Team Member of Vite and Svelte',
    links: [
      { icon: 'github', link: 'https://github.com/dominikg' },
      { icon: 'mastodon', link: 'https://elk.zone/m.webtoo.ls/@dominikg' },
    ],
    sponsor: 'https://github.com/sponsors/dominikg',
  },
]


//     __ _____ _____ _____
//  __|  |   __|     |   | |  JSON for Modern C++ (supporting code)
// |  |  |__   |  |  | | | |  version 3.12.0
// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
//
// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann <https://nlohmann.me>
// SPDX-License-Identifier: MIT

#include "doctest_compatibility.h"

// avoid warning when assert does not abort
DOCTEST_GCC_SUPPRESS_WARNING_PUSH
DOCTEST_GCC_SUPPRESS_WARNING("-Wstrict-overflow")
DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
DOCTEST_CLANG_SUPPRESS_WARNING("-Wstrict-overflow")

/// global variable to record side effect of assert calls
static int assert_counter;

/// set failure variable to true instead of calling assert(x)
#define JSON_ASSERT(x) {if (!(x)) ++assert_counter; }

#include <nlohmann/json.hpp>
using nlohmann::json;

// the test assumes exceptions to work
#if !defined(JSON_NOEXCEPTION)
TEST_CASE("JSON_ASSERT(x)")
{
    SECTION("basic_json(first, second)")
    {
        assert_counter = 0;
        CHECK(assert_counter == 0);

        const json::iterator it{};
        json j;

        // in case assertions do not abort execution, an exception is thrown
        CHECK_THROWS_WITH_AS(json(it, j.end()), "[json.exception.invalid_iterator.201] iterators are not compatible", json::invalid_iterator);

        // check that assertion actually happened
        CHECK(assert_counter == 1);
    }
}
#endif

DOCTEST_GCC_SUPPRESS_WARNING_POP
DOCTEST_CLANG_SUPPRESS_WARNING_POP


import { defineConfig } from 'vite'
import workerPluginTestPlugin from './worker-plugin-test-plugin.js'

export default defineConfig({
  base: '/iife/',
  resolve: {
    alias: {
      '@': import.meta.dirname,
    },
  },
  worker: {
    format: 'iife',
    plugins: () => [workerPluginTestPlugin()],
    rolldownOptions: {
      output: {
        assetFileNames: 'assets/worker_asset-[name]-[hash].[ext]',
        chunkFileNames: 'assets/worker_chunk-[name]-[hash].js',
        // should be overwritten to worker_entry-[name] by the config-test plugin
        entryFileNames: 'assets/worker_-[name].js',
      },
    },
  },
  build: {
    outDir: 'dist/iife',
    assetsInlineLimit: (filePath) =>
      filePath.endsWith('.svg') ? false : undefined,
    manifest: true,
    rolldownOptions: {
      output: {
        assetFileNames: 'assets/[name]-[hash].[ext]',
        chunkFileNames: 'assets/[name]-[hash].js',
        entryFileNames: 'assets/[name].js',
      },
    },
  },
  plugins: [
    workerPluginTestPlugin(),
    {
      name: 'config-test',
      config() {
        return {
          worker: {
            rolldownOptions: {
              output: {
                entryFileNames: 'assets/worker_entry-[name].js',
              },
            },
          },
        }
      },
    },
  ],
  cacheDir: 'node_modules/.vite-iife',
  optimizeDeps: {
    exclude: ['@vitejs/test-dep-self-reference-url-worker'],
  },
})


import http from 'node:http'
import net from 'node:net'
import { afterEach, describe, expect, test, vi } from 'vitest'
import { wildcardHosts } from '../constants'
import { createServer } from '..'
import type { InlineConfig, ViteDevServer } from '..'

const BASE_PORT = 15181

// `server.listen()` would otherwise start a dep scan that crawls every HTML fixture under `__tests__`
const optimizeDeps: InlineConfig['optimizeDeps'] = {
  noDiscovery: true,
  include: [],
}

describe('port detection', () => {
  let blockingServer: http.Server | null = null
  let viteServer: ViteDevServer | null = null

  afterEach(async () => {
    if (viteServer) {
      await viteServer.close()
      viteServer = null
    }

    await new Promise<void>((resolve) => {
      if (blockingServer) {
        blockingServer.close(() => resolve())
        blockingServer = null
      } else {
        resolve()
      }
    })
  })

  async function createSimpleServer(port: number, host: string) {
    const server = http.createServer()
    await new Promise<void>((resolve) => {
      server.listen(port, host, () => resolve())
    })
    return {
      [Symbol.asyncDispose]() {
        return new Promise<void>((resolve) => {
          server.close(() => resolve())
        })
      },
    }
  }

  describe('port fallback', () => {
    test('uses the same ephemeral port on every interface', async () => {
      using listen = vi.spyOn(net.Server.prototype, 'listen')

      viteServer = await createServer({
        root: import.meta.dirname,
        optimizeDeps,
        logLevel: 'silent',
        server: { port: 0, ws: false },
      })
      await viteServer.listen()

      const address = viteServer.httpServer!.address()
      expect(address).toStrictEqual(
        expect.objectContaining({ port: expect.any(Number) }),
      )
      const assignedPort = (address as net.AddressInfo).port
      expect(viteServer._currentServerPort).toBe(assignedPort)
      const [firstWildcardHost, ...remainingWildcardHosts] = wildcardHosts
      expect(
        listen.mock.calls.map(([port, host]) => ({ port, host })),
      ).toStrictEqual([
        { port: 0, host: firstWildcardHost },
        ...remainingWildcardHosts.map((host) => ({
          port: assignedPort,
          host,
        })),
        { port: assignedPort, host: 'localhost' }, // Check configured host
        { port: assignedPort, host: 'localhost' }, // Bind HTTP server
      ])
    })

    test('detects port conflict', async () => {
      await using _blockingServer = await createSimpleServer(
        BASE_PORT,
        'localhost',
      )

      viteServer = await createServer({
        root: import.meta.dirname,
        optimizeDeps,
        logLevel: 'silent',
        server: { port: BASE_PORT, strictPort: false, ws: false },
      })
      await viteServer.listen()

      const address = viteServer.httpServer!.address()
      expect(address).toStrictEqual(
        expect.objectContaining({ port: BASE_PORT + 1 }),
      )
    })

    test('detects multiple port conflict', async () => {
      await using _blockingServer1 = await createSimpleServer(
        BASE_PORT,
        'localhost',
      )
      await using _blockingServer2 = await createSimpleServer(
        BASE_PORT + 1,
        'localhost',
      )

      viteServer = await createServer({
        root: import.meta.dirname,
        optimizeDeps,
        logLevel: 'silent',
        server: { port: BASE_PORT, strictPort: false, ws: false },
      })
      await viteServer.listen()

      const address = viteServer.httpServer!.address()
      expect(address).toStrictEqual(
        expect.objectContaining({ port: BASE_PORT + 2 }),
      )
    })

    test('detects port conflict when server listens on 0.0.0.0', async () => {
      await using _blockingServer = await createSimpleServer(
        BASE_PORT,
        '0.0.0.0',
      )

      viteServer = await createServer({
        root: import.meta.dirname,
        optimizeDeps,
        logLevel: 'silent',
        server: { port: BASE_PORT, strictPort: false, ws: false },
      })
      await viteServer.listen()

      const address = viteServer.httpServer!.address()
      expect(address).toStrictEqual(
        expect.objectContaining({ port: BASE_PORT + 1 }),
      )
    })

    test('detects port conflict when server listens on :: (IPv6)', async (ctx) => {
      let blockingServer
      try {
        blockingServer = await createSimpleServer(BASE_PORT, '::')
      } catch {
        // Skip test if IPv6 is not available on this system
        ctx.skip()
        return
      }
      await using _blockingServer = blockingServer

      viteServer = await createServer({
        root: import.meta.dirname,
        optimizeDeps,
        logLevel: 'silent',
        server: { port: BASE_PORT, strictPort: false, ws: false },
      })
      await viteServer.listen()

      const address = viteServer.httpServer!.address()
      expect(address).toStrictEqual(
        expect.objectContaining({ port: BASE_PORT + 1 }),
      )
    })

    test('wildcard check also runs after EADDRINUSE fallback', async () => {
      // localhost:n occupied
      // 0.0.0.0:n+1 occupied
      // => Vite should pick n+2

      await using _localhostServer = await createSimpleServer(
        BASE_PORT,
        'localhost',
      )
      await using _wildcardServer = await createSimpleServer(
        BASE_PORT + 1,
        '0.0.0.0',
      )

      viteServer = await createServer({
        root: import.meta.dirname,
        optimizeDeps,
        logLevel: 'silent',
        server: {
          port: BASE_PORT,
          strictPort: false,
          ws: false,
        },
      })
      await viteServer.listen()

      const address = viteServer.httpServer!.address()
      expect(address).toStrictEqual(
        expect.objectContaining({ port: BASE_PORT + 2 }),
      )
    })
  })

  test('non-EADDRINUSE errors on wildcard do not block port selection', async () => {
    const originalCreateServer = net.createServer.bind(net)
    using _ = vi.spyOn(net, 'createServer').mockImplementation(() => {
      const server = originalCreateServer()
      const originalListen = server.listen.bind(server)
      // @ts-expect-error this is the overload used internally
      server.listen = (
        port: number,
        host: string,
        ...args: unknown[]
      ): net.Server => {
        if (wildcardHosts.has(host)) {
          process.nextTick(() => {
            const err: NodeJS.ErrnoException = new Error(
              'listen EACCES: permission denied',
            )
            err.code = 'EACCES'
            server.emit('error', err)
          })
          return server
        }
        // @ts-expect-error this is the overload used internally
        return originalListen(port, host, ...args)
      }
      return server
    })

    viteServer = await createServer({
      root: import.meta.dirname,
      optimizeDeps,
      logLevel: 'silent',
      server: { port: BASE_PORT, strictPort: false, ws: false },
    })
    await viteServer.listen()

    const address = viteServer.httpServer!.address()
    expect(address).toStrictEqual(expect.objectContaining({ port: BASE_PORT }))
  })

  test('throws error when port is blocked and strictPort is true', async () => {
    await using _blockingServer = await createSimpleServer(
      BASE_PORT,
      'localhost',
    )

    viteServer = await createServer({
      root: import.meta.dirname,
      optimizeDeps,
      logLevel: 'silent',
      server: { port: BASE_PORT, strictPort: true, ws: false },
    })

    await expect(viteServer.listen()).rejects.toThrow(
      `Port ${BASE_PORT} is already in use`,
    )
  })

  test('allows binding to specific host with strictPort when wildcard port is in use', async () => {
    await using _wildcardServer = await createSimpleServer(BASE_PORT, '0.0.0.0')

    const warnMessages: string[] = []
    viteServer = await createServer({
      root: import.meta.dirname,
      optimizeDeps,
      customLogger: {
        info: () => {},
        warn: (msg) => warnMessages.push(msg),
        warnOnce: () => {},
        error: () => {},
        clearScreen: () => {},
        hasErrorLogged: () => false,
        hasWarned: false,
      },
      server: {
        port: BASE_PORT,
        host: '127.0.0.1',
        strictPort: true,
        ws: false,
      },
    })

    try {
      await viteServer.listen()
    } catch (e) {
      // it may not be allowed to bind to specific host when wildcard port is in use
      expect(() => {
        throw e
      }).toThrow(`Port ${BASE_PORT} is already in use`)
      return
    }

    const address = viteServer.httpServer!.address()
    expect(address).toStrictEqual(expect.objectContaining({ port: BASE_PORT }))
    expect(warnMessages).toContainEqual(expect.stringContaining('wildcard'))
  })

  describe('port reuse on restart', () => {
    test('reuses the OS-assigned port on restart when port is 0', async () => {
      viteServer = await createServer({
        root: import.meta.dirname,
        optimizeDeps,
        logLevel: 'silent',
        server: { port: 0, ws: false },
      })
      await viteServer.listen()

      const address = viteServer.httpServer!.address() as net.AddressInfo
      const assignedPort = address.port

      await viteServer.restart()

      expect(viteServer.httpServer!.address()).toStrictEqual(
        expect.objectContaining({ port: assignedPort }),
      )
    })

    test('reuses the listened port when retrying after a failed listen', async () => {
      await using blockingServer = await createSimpleServer(
        BASE_PORT,
        'localhost',
      )

      viteServer = await createServer({
        root: import.meta.dirname,
        optimizeDeps,
        logLevel: 'silent',
        server: { port: BASE_PORT, ws: false },
      })
      await viteServer.listen()

      const address = viteServer.httpServer!.address() as net.AddressInfo
      const assignedPort = address.port

      await blockingServer[Symbol.asyncDispose]()

      await viteServer.restart()

      expect(viteServer.httpServer!.address()).toStrictEqual(
        expect.objectContaining({ port: assignedPort }),
      )
    })
  })
})


// This module defines the types we use for JSON serialization. We specifically
// omit deserialization, partially because there isn't a clear use case for
// them at this time, but also because deserialization will complicate things.
// Namely, the types below are designed in a way that permits JSON
// serialization with little or no allocation. Allocation is often quite
// convenient for deserialization however, so these types would become a bit
// more complex.

use std::{borrow::Cow, path::Path};

pub(crate) enum Message<'a> {
    Begin(Begin<'a>),
    End(End<'a>),
    Match(Match<'a>),
    Context(Context<'a>),
}

impl<'a> serde::Serialize for Message<'a> {
    fn serialize<S: serde::Serializer>(
        &self,
        s: S,
    ) -> Result<S::Ok, S::Error> {
        use serde::ser::SerializeStruct;

        let mut state = s.serialize_struct("Message", 2)?;
        match *self {
            Message::Begin(ref msg) => {
                state.serialize_field("type", &"begin")?;
                state.serialize_field("data", msg)?;
            }
            Message::End(ref msg) => {
                state.serialize_field("type", &"end")?;
                state.serialize_field("data", msg)?;
            }
            Message::Match(ref msg) => {
                state.serialize_field("type", &"match")?;
                state.serialize_field("data", msg)?;
            }
            Message::Context(ref msg) => {
                state.serialize_field("type", &"context")?;
                state.serialize_field("data", msg)?;
            }
        }
        state.end()
    }
}

pub(crate) struct Begin<'a> {
    pub(crate) path: Option<&'a Path>,
}

impl<'a> serde::Serialize for Begin<'a> {
    fn serialize<S: serde::Serializer>(
        &self,
        s: S,
    ) -> Result<S::Ok, S::Error> {
        use serde::ser::SerializeStruct;

        let mut state = s.serialize_struct("Begin", 1)?;
        state.serialize_field("path", &self.path.map(Data::from_path))?;
        state.end()
    }
}

pub(crate) struct End<'a> {
    pub(crate) path: Option<&'a Path>,
    pub(crate) binary_offset: Option<u64>,
    pub(crate) stats: crate::stats::Stats,
}

impl<'a> serde::Serialize for End<'a> {
    fn serialize<S: serde::Serializer>(
        &self,
        s: S,
    ) -> Result<S::Ok, S::Error> {
        use serde::ser::SerializeStruct;

        let mut state = s.serialize_struct("End", 3)?;
        state.serialize_field("path", &self.path.map(Data::from_path))?;
        state.serialize_field("binary_offset", &self.binary_offset)?;
        state.serialize_field("stats", &self.stats)?;
        state.end()
    }
}

pub(crate) struct Match<'a> {
    pub(crate) path: Option<&'a Path>,
    pub(crate) lines: &'a [u8],
    pub(crate) line_number: Option<u64>,
    pub(crate) absolute_offset: u64,
    pub(crate) submatches: &'a [SubMatch<'a>],
}

impl<'a> serde::Serialize for Match<'a> {
    fn serialize<S: serde::Serializer>(
        &self,
        s: S,
    ) -> Result<S::Ok, S::Error> {
        use serde::ser::SerializeStruct;

        let mut state = s.serialize_struct("Match", 5)?;
        state.serialize_field("path", &self.path.map(Data::from_path))?;
        state.serialize_field("lines", &Data::from_bytes(self.lines))?;
        state.serialize_field("line_number", &self.line_number)?;
        state.serialize_field("absolute_offset", &self.absolute_offset)?;
        state.serialize_field("submatches", &self.submatches)?;
        state.end()
    }
}

pub(crate) struct Context<'a> {
    pub(crate) path: Option<&'a Path>,
    pub(crate) lines: &'a [u8],
    pub(crate) line_number: Option<u64>,
    pub(crate) absolute_offset: u64,
    pub(crate) submatches: &'a [SubMatch<'a>],
}

impl<'a> serde::Serialize for Context<'a> {
    fn serialize<S: serde::Serializer>(
        &self,
        s: S,
    ) -> Result<S::Ok, S::Error> {
        use serde::ser::SerializeStruct;

        let mut state = s.serialize_struct("Context", 5)?;
        state.serialize_field("path", &self.path.map(Data::from_path))?;
        state.serialize_field("lines", &Data::from_bytes(self.lines))?;
        state.serialize_field("line_number", &self.line_number)?;
        state.serialize_field("absolute_offset", &self.absolute_offset)?;
        state.serialize_field("submatches", &self.submatches)?;
        state.end()
    }
}

pub(crate) struct SubMatch<'a> {
    pub(crate) m: &'a [u8],
    pub(crate) replacement: Option<&'a [u8]>,
    pub(crate) start: usize,
    pub(crate) end: usize,
}

impl<'a> serde::Serialize for SubMatch<'a> {
    fn serialize<S: serde::Serializer>(
        &self,
        s: S,
    ) -> Result<S::Ok, S::Error> {
        use serde::ser::SerializeStruct;

        let mut state = s.serialize_struct("SubMatch", 3)?;
        state.serialize_field("match", &Data::from_bytes(self.m))?;
        if let Some(r) = self.replacement {
            state.serialize_field("replacement", &Data::from_bytes(r))?;
        }
        state.serialize_field("start", &self.start)?;
        state.serialize_field("end", &self.end)?;
        state.end()
    }
}

/// Data represents things that look like strings, but may actually not be
/// valid UTF-8. To handle this, `Data` is serialized as an object with one
/// of two keys: `text` (for valid UTF-8) or `bytes` (for invalid UTF-8).
///
/// The happy path is valid UTF-8, which streams right through as-is, since
/// it is natively supported by JSON. When invalid UTF-8 is found, then it is
/// represented as arbitrary bytes and base64 encoded.
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
enum Data<'a> {
    Text { text: Cow<'a, str> },
    Bytes { bytes: &'a [u8] },
}

impl<'a> Data<'a> {
    fn from_bytes(bytes: &[u8]) -> Data<'_> {
        match std::str::from_utf8(bytes) {
            Ok(text) => Data::Text { text: Cow::Borrowed(text) },
            Err(_) => Data::Bytes { bytes },
        }
    }

    #[cfg(unix)]
    fn from_path(path: &Path) -> Data<'_> {
        use std::os::unix::ffi::OsStrExt;

        match path.to_str() {
            Some(text) => Data::Text { text: Cow::Borrowed(text) },
            None => Data::Bytes { bytes: path.as_os_str().as_bytes() },
        }
    }

    #[cfg(not(unix))]
    fn from_path(path: &Path) -> Data<'_> {
        // Using lossy conversion means some paths won't round trip precisely,
        // but it's not clear what we should actually do. Serde rejects
        // non-UTF-8 paths, and OsStr's are serialized as a sequence of UTF-16
        // code units on Windows. Neither seem appropriate for this use case,
        // so we do the easy thing for now.
        Data::Text { text: path.to_string_lossy() }
    }
}

impl<'a> serde::Serialize for Data<'a> {
    fn serialize<S: serde::Serializer>(
        &self,
        s: S,
    ) -> Result<S::Ok, S::Error> {
        use serde::ser::SerializeStruct;

        let mut state = s.serialize_struct("Data", 1)?;
        match *self {
            Data::Text { ref text } => state.serialize_field("text", text)?,
            Data::Bytes { bytes } => {
                // use base64::engine::{general_purpose::STANDARD, Engine};
                // let encoded = STANDARD.encode(bytes);
                state.serialize_field("bytes", &base64_standard(bytes))?;
            }
        }
        state.end()
    }
}

/// Implements "standard" base64 encoding as described in RFC 3548[1].
///
/// We roll our own here instead of bringing in something heavier weight like
/// the `base64` crate. In particular, we really don't care about perf much
/// here, since this is only used for data or file paths that are not valid
/// UTF-8.
///
/// [1]: https://tools.ietf.org/html/rfc3548#section-3
fn base64_standard(bytes: &[u8]) -> String {
    const ALPHABET: &[u8] =
        b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

    let mut out = String::new();
    let mut it = bytes.chunks_exact(3);
    while let Some(chunk) = it.next() {
        let group24 = (usize::from(chunk[0]) << 16)
            | (usize::from(chunk[1]) << 8)
            | usize::from(chunk[2]);
        let index1 = (group24 >> 18) & 0b111_111;
        let index2 = (group24 >> 12) & 0b111_111;
        let index3 = (group24 >> 6) & 0b111_111;
        let index4 = (group24 >> 0) & 0b111_111;
        out.push(char::from(ALPHABET[index1]));
        out.push(char::from(ALPHABET[index2]));
        out.push(char::from(ALPHABET[index3]));
        out.push(char::from(ALPHABET[index4]));
    }
    match it.remainder() {
        &[] => {}
        &[byte0] => {
            let group8 = usize::from(byte0);
            let index1 = (group8 >> 2) & 0b111_111;
            let index2 = (group8 << 4) & 0b111_111;
            out.push(char::from(ALPHABET[index1]));
            out.push(char::from(ALPHABET[index2]));
            out.push('=');
            out.push('=');
        }
        &[byte0, byte1] => {
            let group16 = (usize::from(byte0) << 8) | usize::from(byte1);
            let index1 = (group16 >> 10) & 0b111_111;
            let index2 = (group16 >> 4) & 0b111_111;
            let index3 = (group16 << 2) & 0b111_111;
            out.push(char::from(ALPHABET[index1]));
            out.push(char::from(ALPHABET[index2]));
            out.push(char::from(ALPHABET[index3]));
            out.push('=');
        }
        _ => unreachable!("remainder must have length < 3"),
    }
    out
}

#[cfg(test)]
mod tests {
    use super::*;

    // Tests taken from RFC 4648[1].
    //
    // [1]: https://datatracker.ietf.org/doc/html/rfc4648#section-10
    #[test]
    fn base64_basic() {
        let b64 = |s: &str| base64_standard(s.as_bytes());
        assert_eq!(b64(""), "");
        assert_eq!(b64("f"), "Zg==");
        assert_eq!(b64("fo"), "Zm8=");
        assert_eq!(b64("foo"), "Zm9v");
        assert_eq!(b64("foob"), "Zm9vYg==");
        assert_eq!(b64("fooba"), "Zm9vYmE=");
        assert_eq!(b64("foobar"), "Zm9vYmFy");
    }
}


import * as pathe from 'pathe'
import { isWindows } from '../shared/utils'

const textDecoder = new TextDecoder()

export const decodeBase64: (base64: string) => string = (() => {
  // Capture the binding at module load: realms may legitimately delete
  // `globalThis.Buffer` afterwards (e.g. browser-parity tests), and this
  // decoder runs lazily while preparing stack traces
  const capturedBuffer = typeof Buffer === 'function' ? Buffer : undefined
  if (capturedBuffer && typeof capturedBuffer.from === 'function') {
    return (base64: string) =>
      capturedBuffer.from(base64, 'base64').toString('utf-8')
  }

  return (base64: string) =>
    textDecoder.decode(Uint8Array.from(atob(base64), (c) => c.charCodeAt(0)))
})()

const CHAR_FORWARD_SLASH = 47
const CHAR_BACKWARD_SLASH = 92

const percentRegEx = /%/g
const backslashRegEx = /\\/g
const newlineRegEx = /\n/g
const carriageReturnRegEx = /\r/g
const tabRegEx = /\t/g
const questionRegex = /\?/g
const hashRegex = /#/g

function encodePathChars(filepath: string) {
  if (filepath.includes('%')) filepath = filepath.replace(percentRegEx, '%25')
  // In posix, backslash is a valid character in paths:
  if (!isWindows && filepath.includes('\\'))
    filepath = filepath.replace(backslashRegEx, '%5C')
  if (filepath.includes('\n')) filepath = filepath.replace(newlineRegEx, '%0A')
  if (filepath.includes('\r'))
    filepath = filepath.replace(carriageReturnRegEx, '%0D')
  if (filepath.includes('\t')) filepath = filepath.replace(tabRegEx, '%09')
  return filepath
}

export const posixDirname: (path: string) => string = pathe.dirname
export const posixResolve: (...paths: string[]) => string = pathe.resolve

export function posixPathToFileHref(posixPath: string): string {
  let resolved = posixResolve(posixPath)
  // path.resolve strips trailing slashes so we must add them back
  const filePathLast = posixPath.charCodeAt(posixPath.length - 1)
  if (
    (filePathLast === CHAR_FORWARD_SLASH ||
      (isWindows && filePathLast === CHAR_BACKWARD_SLASH)) &&
    resolved[resolved.length - 1] !== '/'
  )
    resolved += '/'

  // Call encodePathChars first to avoid encoding % again for ? and #.
  resolved = encodePathChars(resolved)

  // Question and hash character should be included in pathname.
  // Therefore, encoding is required to eliminate parsing them in different states.
  // This is done as an optimization to not creating a URL instance and
  // later triggering pathname setter, which impacts performance
  if (resolved.includes('?')) resolved = resolved.replace(questionRegex, '%3F')
  if (resolved.includes('#')) resolved = resolved.replace(hashRegex, '%23')
  return new URL(`file://${resolved}`).href
}

export function toWindowsPath(path: string): string {
  return path.replace(/\//g, '\\')
}


// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.

// Test with a more mallocs than frees, but no leak.
#include <cstdint>
#include <cstddef>

const int kAllocatedPointersSize = 10000;
int NumAllocatedPointers = 0;
int *AllocatedPointers[kAllocatedPointersSize];

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
  if (NumAllocatedPointers < kAllocatedPointersSize)
    AllocatedPointers[NumAllocatedPointers++] = new int;
  return 0;
}


# Object Order

The [JSON standard](https://tools.ietf.org/html/rfc8259.html) defines objects as "an unordered collection of zero or more name/value pairs". As such, an implementation does not need to preserve any specific order of object keys.

## Default behavior: sort keys

The default type `nlohmann::json` uses a `std::map` to store JSON objects, and thus stores object keys **sorted alphabetically**.

??? example

    ```cpp
    #include <iostream>
    #include <nlohmann/json.hpp>

    using json = nlohmann::json;

    int main()
    {
        json j;
        j["one"] = 1;
        j["two"] = 2;
        j["three"] = 3;

        std::cout << j.dump(2) << '\n';
    }
    ```

    Output:

    ```json
    {
      "one": 1,
      "three": 3,
      "two": 2
    }
    ```

## Alternative behavior: preserve insertion order

If you do want to preserve the **insertion order**, you can use the type [`nlohmann::ordered_json`](../api/ordered_json.md).

??? example

    ```cpp
    --8<-- "examples/ordered_json.cpp"
    ```

    Output:

    ```json
    --8<-- "examples/ordered_json.output"
    ```

Alternatively, you can use a more sophisticated ordered map like [`tsl::ordered_map`](https://github.com/Tessil/ordered-map) ([integration](https://github.com/nlohmann/json/issues/546#issuecomment-304447518)) or [`nlohmann::fifo_map`](https://github.com/nlohmann/fifo_map) ([integration](https://github.com/nlohmann/json/issues/485#issuecomment-333652309)).

The [`ordered_map`](../api/ordered_map.md) behind `nlohmann::ordered_json` is deliberately minimal and has no lookup
index, so every key access is a linear scan and building an object of `n` keys costs O(n²). This is unnoticeable at
typical object sizes but becomes significant for objects with many thousands of keys; see
[`ordered_map` complexity](../api/ordered_map.md#complexity). The alternatives above keep a lookup index and do not
have this cost.

### Notes on parsing

Note that you also need to call the right [`parse`](../api/basic_json/parse.md) function when reading from a file.
Assume file `input.json` contains the JSON object above:

```json
{
  "one": 1,
  "two": 2,
  "three": 3
}
```

!!! success "Right way"

    The following code correctly calls the `parse` function from `nlohmann::ordered_json`:

    ```cpp
    std::ifstream i("input.json");
    auto j = nlohmann::ordered_json::parse(i);
    std::cout << j.dump(2) << std::endl;
    ```

    The output will be:

    ```json
    {
      "one": 1,
      "two": 2,
      "three": 3
    }
    ```

??? failure "Wrong way"

    The following code incorrectly calls the `parse` function from `nlohmann::json` which does not preserve the
    insertion order, but sorts object keys. Assigning the result to `nlohmann::ordered_json` compiles, but does not
    restore the order from the input file.

    ```cpp
    std::ifstream i("input.json");
    nlohmann::ordered_json j = nlohmann::json::parse(i);
    std::cout << j.dump(2) << std::endl;
    ```

    The output will be:

    ```json
    {
      "one": 1,
      "three": 3,
      "two": 2
    }
    ```


import util from 'node:util'
import path from 'node:path'
import { describe, expect, test } from 'vitest'
import type { ModuleTypeFilter } from 'rolldown'
import {
  type StringFilter,
  createCodeFilter,
  createFilterForTransform,
  createIdFilter,
} from '../../plugins/pluginFilter'

describe('createIdFilter', () => {
  const filters = [
    { inputFilter: undefined, cases: undefined },
    {
      inputFilter: 'foo.js',
      cases: [
        { id: 'foo.js', expected: true },
        { id: 'foo.ts', expected: false },
        { id: '\0foo.js', expected: false },
        { id: '\0' + path.resolve('foo.js'), expected: false },
      ],
    },
    {
      inputFilter: ['foo.js'],
      cases: [
        { id: 'foo.js', expected: true },
        { id: 'foo.ts', expected: false },
      ],
    },
    {
      inputFilter: { include: 'foo.js' },
      cases: [
        { id: 'foo.js', expected: true },
        { id: 'foo.ts', expected: false },
      ],
    },
    {
      inputFilter: { include: '*.js' },
      cases: [
        { id: 'foo.js', expected: true },
        { id: 'foo.ts', expected: false },
      ],
    },
    {
      inputFilter: { include: /\.js$/ },
      cases: [
        { id: 'foo.js', expected: true },
        { id: 'foo.ts', expected: false },
      ],
    },
    {
      inputFilter: { include: /\/foo\.js$/ },
      cases: [
        { id: 'a/foo.js', expected: true },
        ...(process.platform === 'win32'
          ? [{ id: 'a\\foo.js', expected: true }]
          : []),
        { id: 'a_foo.js', expected: false },
      ],
    },
    {
      inputFilter: { include: [/\.js$/] },
      cases: [
        { id: 'foo.js', expected: true },
        { id: 'foo.ts', expected: false },
      ],
    },
    {
      inputFilter: { exclude: 'foo.js' },
      cases: [
        { id: 'foo.js', expected: false },
        { id: 'foo.ts', expected: true },
      ],
    },
    {
      inputFilter: { exclude: '*.js' },
      cases: [
        { id: 'foo.js', expected: false },
        { id: 'foo.ts', expected: true },
      ],
    },
    {
      inputFilter: { exclude: /\.js$/ },
      cases: [
        { id: 'foo.js', expected: false },
        { id: 'foo.ts', expected: true },
      ],
    },
    {
      inputFilter: { exclude: [/\.js$/] },
      cases: [
        { id: 'foo.js', expected: false },
        { id: 'foo.ts', expected: true },
      ],
    },
    {
      inputFilter: { include: 'foo.js', exclude: 'bar.js' },
      cases: [
        { id: 'foo.js', expected: true },
        { id: 'bar.js', expected: false },
        { id: 'baz.js', expected: false },
      ],
    },
    {
      inputFilter: { include: '*.js', exclude: 'foo.*' },
      cases: [
        { id: 'foo.js', expected: false }, // exclude has higher priority
        { id: 'bar.js', expected: true },
        { id: 'foo.ts', expected: false },
      ],
    },
    {
      inputFilter: '/virtual/foo',
      cases: [{ id: '/virtual/foo', expected: true }],
    },
  ]

  for (const filter of filters) {
    test(`${util.inspect(filter.inputFilter)}`, () => {
      const idFilter = createIdFilter(filter.inputFilter, '')
      if (!filter.cases) {
        expect(idFilter).toBeUndefined()
        return
      }
      expect(idFilter).not.toBeUndefined()

      for (const testCase of filter.cases) {
        const { id, expected } = testCase
        expect(idFilter!(id), id).toBe(expected)
      }
    })
  }
})

describe('createCodeFilter', () => {
  const filters = [
    { inputFilter: undefined, cases: undefined },
    {
      inputFilter: 'import.meta',
      cases: [
        { code: 'import.meta', expected: true },
        { code: 'import_meta', expected: false },
      ],
    },
    {
      inputFilter: ['import.meta'],
      cases: [
        { code: 'import.meta', expected: true },
        { code: 'import_meta', expected: false },
      ],
    },
    {
      inputFilter: { include: 'import.meta' },
      cases: [
        { code: 'import.meta', expected: true },
        { code: 'import_meta', expected: false },
      ],
    },
    {
      inputFilter: { include: /import\.\w+/ },
      cases: [
        { code: 'import.meta', expected: true },
        { code: 'import_meta', expected: false },
      ],
    },
    {
      inputFilter: { include: [/import\.\w+/] },
      cases: [
        { code: 'import.meta', expected: true },
        { code: 'import_meta', expected: false },
      ],
    },
    {
      inputFilter: { exclude: 'import.meta' },
      cases: [
        { code: 'import.meta', expected: false },
        { code: 'import_meta', expected: true },
      ],
    },
    {
      inputFilter: { exclude: /import\.\w+/ },
      cases: [
        { code: 'import.meta', expected: false },
        { code: 'import_meta', expected: true },
      ],
    },
    {
      inputFilter: { exclude: [/import\.\w+/] },
      cases: [
        { code: 'import.meta', expected: false },
        { code: 'import_meta', expected: true },
      ],
    },
    {
      inputFilter: { include: 'import.meta', exclude: 'import_meta' },
      cases: [
        { code: 'import.meta', expected: true },
        { code: 'import_meta', expected: false },
        { code: 'importmeta', expected: false },
      ],
    },
    {
      inputFilter: { include: /import\.\w+/, exclude: /\w+\.meta/ },
      cases: [
        { code: 'import.meta', expected: false }, // exclude has higher priority
        { code: 'import.foo', expected: true },
        { code: 'foo.meta', expected: false },
      ],
    },
  ]

  for (const filter of filters) {
    test(`${util.inspect(filter.inputFilter)}`, () => {
      const codeFilter = createCodeFilter(filter.inputFilter)
      if (!filter.cases) {
        expect(codeFilter).toBeUndefined()
        return
      }
      expect(codeFilter).not.toBeUndefined()

      for (const testCase of filter.cases) {
        const { code, expected } = testCase
        expect(codeFilter!(code), code).toBe(expected)
      }
    })
  }
})

describe('createFilterForTransform', () => {
  type Filters = {
    inputFilter: [
      idFilter: StringFilter | undefined,
      codeFilter: StringFilter | undefined,
      moduleTypeFilter?: ModuleTypeFilter | undefined,
    ]
    cases:
      | {
          id: string
          code: string
          moduleType?: string
          expected: boolean
        }[]
      | undefined
  }[]
  const filters: Filters = [
    { inputFilter: [undefined, undefined], cases: undefined },
    {
      inputFilter: ['*.js', undefined],
      cases: [
        { id: 'foo.js', code: 'foo', expected: true },
        { id: 'foo.ts', code: 'foo', expected: false },
      ],
    },
    {
      inputFilter: [undefined, 'import.meta'],
      cases: [
        { id: 'foo.js', code: 'import.meta', expected: true },
        { id: 'foo.js', code: 'import_meta', expected: false },
      ],
    },
    {
      inputFilter: [{ exclude: '*.js' }, 'import.meta'],
      cases: [
        { id: 'foo.js', code: 'import.meta', expected: false },
        { id: 'foo.js', code: 'import_meta', expected: false },
        { id: 'foo.ts', code: 'import.meta', expected: true },
        { id: 'foo.ts', code: 'import_meta', expected: false },
      ],
    },
    {
      inputFilter: [{ include: 'foo.ts', exclude: '*.js' }, 'import.meta'],
      cases: [
        { id: 'foo.js', code: 'import.meta', expected: false },
        { id: 'foo.js', code: 'import_meta', expected: false },
        { id: 'foo.ts', code: 'import.meta', expected: true },
        { id: 'foo.ts', code: 'import_meta', expected: false },
      ],
    },
    {
      inputFilter: [
        { include: 'a*', exclude: '*b' },
        { include: 'a', exclude: 'b' },
      ],
      cases: [
        { id: 'ab', code: '', expected: false },
        { id: 'a', code: 'b', expected: false },
        { id: 'a', code: '', expected: false },
        { id: 'c', code: 'a', expected: false },
        { id: 'a', code: 'a', expected: true },
      ],
    },
    {
      inputFilter: [{ include: 'a*', exclude: '*b' }, { exclude: 'b' }],
      cases: [
        { id: 'ab', code: '', expected: false },
        { id: 'a', code: 'b', expected: false },
        { id: 'a', code: '', expected: true },
        { id: 'c', code: 'a', expected: false },
        { id: 'a', code: 'a', expected: true },
      ],
    },
    {
      inputFilter: [undefined, undefined, ['js']],
      cases: [
        { id: 'foo.js', code: 'foo', moduleType: 'js', expected: true },
        { id: 'foo.ts', code: 'foo', moduleType: 'ts', expected: false },
      ],
    },
    {
      inputFilter: [undefined, undefined, { include: ['js'] }],
      cases: [
        { id: 'foo.js', code: 'foo', moduleType: 'js', expected: true },
        { id: 'foo.ts', code: 'foo', moduleType: 'ts', expected: false },
      ],
    },
  ]

  for (const filter of filters) {
    test(`${util.inspect(filter.inputFilter)}`, () => {
      const [idFilter, codeFilter, moduleTypeFilter] = filter.inputFilter
      const filterForTransform = createFilterForTransform(
        idFilter,
        codeFilter,
        moduleTypeFilter,
        '',
      )
      if (!filter.cases) {
        expect(filterForTransform).toBeUndefined()
        return
      }
      expect(filterForTransform).not.toBeUndefined()

      for (const testCase of filter.cases) {
        const { id, code, moduleType, expected } = testCase
        expect(
          filterForTransform!(id, code, moduleType ?? 'js'),
          util.inspect({ id, code, moduleType }),
        ).toBe(expected)
      }
    })
  }
})


test elements below should show circles and their url

Denied .env


export { a, b } from './source'

if (import.meta.hot) {
  // import.meta.hot.accept('./source', (m) => {
  //   log(`accept-named reexport:${m.a},${m.b}`)
  // })
  import.meta.hot.acceptExports('a', (m) => {
    log(`accept-named reexport:${m.a},${m.b}`)
  })
}


# <small>nlohmann::</small>ordered_map

```cpp
template<class Key, class T, class IgnoredLess = std::less<Key>,
         class Allocator = std::allocator<std::pair<const Key, T>>>
struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>;
```

A minimal map-like container that preserves insertion order for use within [`nlohmann::ordered_json`](ordered_json.md)
(`nlohmann::basic_json<ordered_map>`).

## Template parameters

`Key`
:   key type

`T`
:   mapped type

`IgnoredLess`
:   comparison function (ignored and only added to ensure compatibility with `#!cpp std::map`)

`Allocator`
:   allocator type

## Iterator invalidation

The type uses a `std::vector` to store object elements. Therefore, adding elements can yield a reallocation in which
case all iterators (including the `end()` iterator) and all references to the elements are invalidated.

## Member types

- **key_type** - key type (`Key`)
- **mapped_type** - mapped type (`T`)
- **Container** - base container type (`#!cpp std::vector<std::pair<const Key, T>, Allocator>`)
- **iterator**
- **const_iterator**
- **size_type**
- **value_type**
- **key_compare** - key comparison function
```cpp
std::equal_to<Key>  // until C++14

std::equal_to<>     // since C++14
```

## Member functions

- (constructor)
- (destructor)
- **emplace**
- **operator\[\]**
- **at**
- **erase**
- **count**
- **find**
- **insert**

## Complexity

Because the elements are stored in a `std::vector` in insertion order, there is no index to look a key up by. Every
key-based operation performs a **linear scan** over the stored elements. With `n` denoting the number of elements in the
container:

| Operation                              | Complexity     | Note                                                     |
|----------------------------------------|----------------|----------------------------------------------------------|
| **emplace**                            | O(n)           | scans for an existing key, then appends (amortized O(1)) |
| **operator\[\]**                       | O(n)           | delegates to **emplace** (non-const) or **at** (const)   |
| **at**                                 | O(n)           | throws `#!cpp std::out_of_range` if the key is not found |
| **find**                               | O(n)           |                                                          |
| **count**                              | O(n)           | the result is always 0 or 1                              |
| **erase(key)**                         | O(n)           | scan, then move the remaining elements one position down |
| **erase(pos)**, **erase(first, last)** | O(n)           | moves all elements after the erased range                |
| **insert(value)**                      | O(n)           | equivalent to **emplace**                                |
| **insert(first, last)**                | O((n + m) * m) | for `m` inserted elements                                |

This differs from `#!cpp std::map`, where the same operations are O(log n).

!!! warning "Quadratic cost of building large objects"

    Because every insertion scans all elements inserted so far, building an object of `n` distinct keys costs
    **O(n²)** in total. This applies to filling an [`ordered_json`](ordered_json.md) object key by key as well as to
    parsing one, since the parser inserts each key as it is read.

    The cost is negligible for the object sizes typically found in configuration files or API payloads, but it grows
    steeply for machine-generated objects with many thousands of keys. Measured with `-O2 -DNDEBUG` for parsing a flat
    object of `n` keys, relative to `#!cpp nlohmann::json` (which uses `#!cpp std::map`):

    | `n`    | `json` | `ordered_json` | factor |
    |--------|--------|----------------|--------|
    | 2000   | 0.7 ms | 3.6 ms         | 5×     |
    | 4000   | 0.8 ms | 14.0 ms        | 19×    |
    | 8000   | 1.6 ms | 67.8 ms        | 43×    |
    | 16 000 | 3.3 ms | 181.6 ms       | 54×    |

    If key order matters for objects of that size, consider a container with a lookup index, such as
    [`tsl::ordered_map`](https://github.com/Tessil/ordered-map)
    ([integration](https://github.com/nlohmann/json/issues/546#issuecomment-304447518)), as the object type -- see
    [object order](../features/object_order.md).

## Examples

??? example

    The example shows the different behavior of `std::map` and `nlohmann::ordered_map`.

    ```cpp
    --8<-- "examples/ordered_map.cpp"
    ```

    Output:

    ```json
    --8<-- "examples/ordered_map.output"
    ```

## See also

- [ordered_json](ordered_json.md)

## Version history

- Added in version 3.9.0 to implement [`nlohmann::ordered_json`](ordered_json.md).
- Added **key_compare** member in version 3.11.0.


const escapeHtmlReplaceMap = {
  '&': '&',
  "'": ''',
  '`': '`',
  '"': '"',
  '<': '<',
  '>': '>',
}

/**
 * @param {string} string
 * @returns {string}
 */
export function escapeHtml(string) {
  return string.replace(/[&'`"<>]/g, (match) => escapeHtmlReplaceMap[match])
}