diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fffc545..2b1e933 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,26 +1,35 @@ name: CI -on: push +on: + push: + branches: [master] + pull_request: + branches: [master] + +permissions: + contents: read jobs: - build: + build-and-test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - - uses: actions/setup-node@v3 + - name: Check out repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: thomashoneyman/setup-purescript@main + - name: Set up Node.js + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: - purescript: "0.15.4" - spago: "0.20.9" + node-version: 22 + cache: npm - - name: Cache PureScript dependencies - uses: actions/cache@v2 - with: - key: ${{ runner.os }}-spago-${{ hashFiles('**/*.dhall') }} - path: | - .spago - output + - name: Install pinned tools + run: npm ci + + - name: Check formatting + run: npm run format:check + + - name: Build + run: npm run build -- --strict - - run: npm test + - name: Test + run: npm test diff --git a/.gitignore b/.gitignore index 77f2c6a..50268d8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,13 +1,5 @@ -/bower_components/ /node_modules/ -/.pulp-cache/ /output/ -/generated-docs/* -!/generated-docs/md -/generated-docs/md/* -!/generated-docs/md/React.Halo.* -/.psc-package/ -/.psc* -/.purs* -/.psa* -/.spago +/.spago/ +/.spec-results +/generated-docs/ diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..8502441 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,35 @@ +# Repository instructions for agents + +Use this file as the repository control plane. Do not treat it as a substitute for the reader and maintainer documentation. + +## Read the relevant sources first + +For an unfamiliar task, route yourself by scope: + +- Read [README.md](README.md) for the product boundary and current public mental model. +- Use the [guide index](docs/guide.md) to select the relevant public contract: [actions and state](docs/guide/actions-and-state.md), [managed work](docs/guide/managed-work.md), or [lifecycle and resources](docs/guide/lifecycle-and-resources.md). +- Read [docs/architecture.md](docs/architecture.md) before changing runtime ownership, interpreters, concurrency, subscriptions, or error handling. +- Read [CONTRIBUTING.md](CONTRIBUTING.md) for setup, validation, and pull request readiness. +- Inspect [`React.Halo`](src/React/Halo.purs) and the public module that owns an API before changing its contract. +- Inspect the corresponding modules under `test/Test/Halo/` before changing behavior; tests are executable contracts for runtime invariants. + +Before changing dependencies or developer commands, inspect `package.json`, `spago.yaml`, and `.github/workflows/ci.yml`. `package.json` owns tool pins and scripts; `spago.yaml` owns PureScript dependencies and the package set; CI owns automated pull request checks. + +## Preserve repository boundaries + +- Keep `React.Halo` as the intentional public API root. Keep the state-focused API in the separately qualified `React.Halo.Task`; do not flatten its generic names through the root. Do not expose internal runtime ownership types as a shortcut. +- Keep React integration in the component/hook boundary and runtime ownership in `React.Halo.Internal.Runtime`. Read the architecture document instead of duplicating its rules here. +- Keep application capabilities routed through the application monad and its `m ~> Aff` interpreter. +- Do not add npm runtime dependencies or an npm runtime entry point. The npm package is development tooling only. +- Update public docs, compile-checked examples, and focused deterministic tests when public behavior changes. +- Do not hand-edit or commit `generated-docs/`, `output/`, `.spago/`, or `node_modules/`; they are ignored generated or dependency state. + +## Validate completion + +Use focused checks while iterating. Before declaring a repository change complete, run the full sequence in [CONTRIBUTING.md](CONTRIBUTING.md): format check, strict and pedantic build, full tests, and docs generation. Review the final diff, verify local documentation links, and run a whitespace check. Report any skipped, failed, or unavailable validation precisely. + +There is no real DOM fixture. Describe successful runtime tests and compile checks accurately; do not claim browser mounting coverage. + +## Require explicit approval for external actions + +Do not push commits, publish packages or documentation, create a release, edit GitHub or pull request state, or change any other external resource without current, action-specific authorization. Repository change approval does not imply release or publication approval. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..d9ca349 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,55 @@ +# Contributing + +This guide covers local setup, validation, and pull request readiness. Start with the [README](README.md) for the public mental model, use the [guide index](docs/guide.md) to find the relevant usage chapter, and read the [architecture notes](docs/architecture.md) before changing runtime ownership or cancellation behavior. + +## Set up the checkout + +Use Node.js 22 with npm to match CI, then install the locked development tools: + +```console +npm ci +``` + +`package.json` is the source of truth for tool pins and npm scripts. `spago.yaml` owns the PureScript dependencies and package set. CI owns the automated checks run for pull requests. + +Halo has no npm runtime entry point or npm runtime dependencies. Do not add an npm runtime dependency to provide behavior that belongs in PureScript or an existing PureScript package. Add or change PureScript dependencies in `spago.yaml`. + +## Develop and validate + +During implementation, run the smallest relevant build or test that gives useful feedback. Changes to runtime ownership, cancellation, subscriptions, interpreters, or public behavior need focused regression coverage in the corresponding test module. + +Before marking a pull request ready, run the full local validation sequence from the repository root: + +```console +npm run format:check +npm run build -- --strict --pedantic-packages +npm test +npx spago docs +``` + +Use `npm run format` to apply the repository formatter when the format check fails. A focused check helps iteration but does not replace the full sequence before review. + +The documentation command writes generated API pages to `generated-docs/`. Spago also writes build and dependency state to `output/` and `.spago/`. These paths are ignored; do not hand-edit or commit them. + +## Keep behavior, tests, and docs aligned + +`React.Halo` is the public API root; the generic state-focused names in `React.Halo.Task` form a separate qualified surface. When a change affects either module's exported types or behavior: + +- update the relevant public module documentation; +- update the README or guide when their guidance changes, and keep exact API contracts in public source comments used by generated documentation; +- keep examples in `test/Test/Halo/DocExamples.purs` compiling; and +- add or update deterministic tests for the changed invariant. + +Use [docs/architecture.md](docs/architecture.md) to find the runtime contract and the tests that protect it. The runtime tests exercise ownership directly without a real DOM fixture, so report validation as runtime or compile coverage rather than as a mounted-browser test. + +Documentation-only changes still require link inspection and documentation generation. Run the complete validation sequence when preparing the pull request so CI-facing code, examples, and package checks remain covered. + +## Check pull request readiness + +Before requesting review, confirm that: + +- the change is focused and its public effect is clear; +- formatting, strict and pedantic build, full tests, and docs generation pass; +- public API changes include matching documentation and tests; +- generated or dependency output is not staged; and +- the final diff contains only intended files and no whitespace errors. diff --git a/README.md b/README.md index 3bddd76..e866839 100644 --- a/README.md +++ b/README.md @@ -1,126 +1,177 @@ # React Halo -Halo is a [Halogen](https://github.com/purescript-halogen/purescript-halogen)-inspired interface for React. +Halo gives a PureScript React component typed actions, local state, and a safe boundary for application effects. Application logic remains in its own monad; Halo owns the UI work started by a React component. -It is available as a hook: `useHalo`; for building entire components there is `component`. +Use Halo when several interactions share state or asynchronous work must be cancelled with the component. For one request derived directly from render dependencies, `React.Basic.Hooks.Aff.useAff` is usually simpler. -## Documentation - -Module documentation is [published on Pursuit](http://pursuit.purescript.org/packages/purescript-react-halo). +## Choose a React entry point -## Using with [Spago](https://github.com/purescript/spago) +Use `component` when Halo owns the complete component: -`$ spago install react-halo` -or -`$ npx spago install react-halo` - -## What does Halo provide? +```purescript +profileComponent env = + Halo.component "Profile" (runAppM env) + { initialState + , handlers + , onError + , render + } +``` -Whether you are using the hook or one of the component helpers, the main feature that Halo provides is the `eval` function. It looks like: +Use `useHalo` when the render function also uses other hooks: ```purescript -Lifecycle props action -> HaloM props state action m Unit +halo <- Halo.useHalo (runAppM env) + { props + , initialState + , handlers + , onError + } + +-- halo.state +-- halo.tasks +-- halo.dispatch ``` -where `Lifecycle` is: +Both entry points receive an interpreter from the application's monad to `Aff`. They expose current component state, an immutable task view, and synchronous action dispatch. `component` also passes current props to its renderer. + +## Understand the core model + +Actions describe UI events, handlers perform component work, and rendering dispatches the next action: ```purescript -data Lifecycle props action - = Initialize -- when the component mounts - | Update props -- when the props change, passing the previous props - | Action action -- when an action is dispatched, passing the action - | Finalize -- when the component unmounts +data Action + = Rename String + | LoadProfile + +handlers = Halo.defaultHandlers + { onAction = case _ of + Rename name -> + modify_ _ { name = name } + + LoadProfile -> do + profile <- lift Profile.load + modify_ _ { profile = Just profile } + } ``` -The helper `mkEval` exists to make this easier to work with: +`HaloM props state action m` owns component state and props while preserving application capabilities in `m`: ```purescript -data Action - = LoadRemoteState - | PersistRemoteState - | ... +type UI a = Halo.HaloM Props State Action AppM a -handleAction :: forall props state m. Action -> HaloM props state Action m Unit +newtype AppM a = AppM (ReaderT Env Aff a) -eval = Halo.mkEval Halo.defaultEval { initialize = Just LoadRemoteState, finalize = Just PersistRemoteState, handleAction = handleAction } +runAppM :: Env -> AppM ~> Aff +runAppM env (AppM program) = runReaderT program env ``` -`HaloM` is also a monad transformer, and so you can lift any monad `m` logic into `HaloM`. Just be aware that in order to run the logic, Halo requires that you `hoist` (convert) your chosen monad into `Aff` before returning it. +Standard transformer `lift` crosses that boundary. Each dispatched action starts an independent handler, so long-running handlers can overlap. React deactivation fences every handler before requesting cancellation. -### Hoisting +Rendering reads state and dispatches actions synchronously: ```purescript -hoist :: forall props state action m m'. Functor m => (m ~> m') -> HaloM props state action m ~> HaloM props state action m' +render { state, dispatch } = + R.button + { onClick: capture_ (dispatch LoadProfile) + , children: [ R.text state.name ] + } ``` -Example: +## Choose the ownership mechanism -```purescript --- Inverting a reader -hoistReaderT :: - forall props state action env m. - HaloM props state action (ReaderT env m) ~> - ReaderT env (HaloM props state action m) -hoistReaderT x = do - env <- ask - lift (Halo.hoist (flip runReaderT env) x) -``` +Start work directly in an action handler. Use a stronger mechanism only when the interaction needs it. + +| Need | Use | +|---|---| +| Handle one UI event | action handler | +| Retain typed idle, active, failure, and success state | managed task | +| Let work outlive its launching handler | component-owned fork | +| Receive actions from an external event source | emitter subscription | +| Release another synchronous resource | registered cleanup | -### Working with props +A task stores a typed outcome in component state and renders through the matching task view: ```purescript -props :: forall props action state m. HaloM props state action m props -``` +type State = + { search :: Task.State SearchError Results + } -Example: +searchSlot :: Task.Slot "search" State SearchError Results +searchSlot = Task.slot (Proxy :: Proxy "search") -```purescript -fireOnChange :: - forall props state action m a. - MonadEffect m => - HaloM { onChange :: a -> Effect Unit | props } { value :: a | state } action m Unit -fireOnChange = do - { onChange } <- Halo.props - { value } <- Halo.get - liftEffect (onChange value) +Search query -> Task.supersede searchSlot do + lift (Search.run query) + +case Task.toStatus tasks searchSlot of + Task.Idle -> renderPrompt + Task.Active -> renderSpinner + Task.Failed error -> renderError error + Task.Succeeded results -> renderResults results ``` -### Working with state +`Task.slot` uses one type-level label as both record field and identity. Use `Task.slotAt` only for a nested or custom lawful focus. Task bodies remain ordinary `HaloM` values returning `Either error result`. -`HaloM` doesn't have any special interface for reading and modifying state, instead providing an instance of [MonadState](https://pursuit.purescript.org/packages/purescript-transformers/docs/Control.Monad.State.Class) for flexibility. +A fork is an independently cancellable component process: -### Subscriptions +```purescript +fiber <- Halo.fork synchronize +Halo.kill fiber +``` -Subscriptions registered using these functions are automatically tracked by Halo. +Subscriptions turn external callbacks into actions: ```purescript -subscribe :: forall props state action m. Emitter action -> HaloM props state action m SubscriptionId - -unsubscribe :: forall props state action m. SubscriptionId -> HaloM props state action m Unit +names = Halo.makeEmitter \emit -> source.listen emit +actions = NameChanged <$> names +void $ Halo.subscribe actions ``` -`Emitter` is from the `purescript-halogen-subscriptions` library. - -There is also a version for subscriptions that want to unsubscribe themselves: +Other synchronous resources can register cleanup directly: ```purescript -subscribe' :: forall props state action m. (SubscriptionId -> Emitter action) -> HaloM props state action m SubscriptionId +cleanupId <- Halo.registerCleanup removeListener +Halo.releaseCleanup cleanupId ``` -Any subscriptions that remain when the component is unmounted are automatically unsubscribed. This prevents requiring manual clean up in the `Finalize` lifecycle event. Also note that new subscriptions will not be created once the `Finalize` event has been fired. +React cleanup is synchronous. Put asynchronous release in an Aff finalizer owned by a handler, task, or fork rather than an `onDeactivate` callback. -### Forking +## Install this unreleased version -Also provided are functions for creating and killing forks which launch processes in separate "threads" (or as useful an approximation as we can get in JavaScript): +The API on this branch is not published yet; the PureScript Registry currently resolves `react-halo` to v3. This branch uses the PureScript and Spago versions pinned in [`package.json`](package.json). -```purescript -fork :: forall props state action m. HaloM props state action m Unit -> HaloM props state action m ForkId +Add a checkout as a local Spago package and declare the dependencies used by your application: -kill :: forall props state action m. ForkId -> HaloM props state action m Unit +```yaml +package: + dependencies: + - aff + - console + - effect + - either + - exceptions + - prelude + - react-basic-dom + - react-basic-hooks + - react-halo + - transformers + +workspace: + extraPackages: + react-halo: + path: ../purescript-react-halo +``` + +After v4 is published, replace the local override with a registry installation: + +```console +spago install aff console effect either exceptions prelude react-basic-dom react-basic-hooks react-halo transformers ``` -Similarly to subscriptions, when the component unmounts all still-running forks will be killed. However new forks _can_ be created during the `Finalize` phase but there is no way of killing them (as with Halogen). +`react-basic-dom` is used by the examples, not required by Halo itself. Applications also need the JavaScript packages required by `react-basic-hooks`, including React. Halo has no npm runtime entry point or npm runtime dependencies. + +## Documentation -### Parallelism +The [guide](docs/guide.md) covers complete usage and ownership choices. Generate exact API documentation from public source comments with `npx spago docs --offline`. Maintainers changing runtime ownership should also read the [architecture notes](docs/architecture.md) and [contributor guide](CONTRIBUTING.md). -Finally `HaloM` provides an instance of `Parallel` for converting back and forth between `HaloAp`, it's applicative counterpart. This allows any logic to be easily converted to run in `parallel` or `sequential`ly. +Halo does not provide global state, server caching, backpressure queues, or a detached scheduler. The deterministic suite models React setup-cleanup-setup at the runtime boundary; the repository does not yet contain a real DOM/StrictMode mounting fixture. diff --git a/bower.json b/bower.json deleted file mode 100644 index 762a086..0000000 --- a/bower.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "name": "purescript-react-halo", - "license": [ - "BSD-3-Clause" - ], - "repository": { - "type": "git", - "url": "https://github.com/robertdp/purescript-react-halo.git" - }, - "ignore": [ - "**/.*", - "node_modules", - "bower_components", - "output" - ], - "dependencies": { - "purescript-aff": "^v7.0.0", - "purescript-bifunctors": "^v6.0.0", - "purescript-effect": "^v4.0.0", - "purescript-either": "^v6.1.0", - "purescript-foldable-traversable": "^v6.0.0", - "purescript-free": "^v7.0.0", - "purescript-freeap": "^v7.0.0", - "purescript-halogen-subscriptions": "https://github.com/purescript-halogen/purescript-halogen-subscriptions.git#v2.0.0", - "purescript-maybe": "^v6.0.0", - "purescript-newtype": "^v5.0.0", - "purescript-ordered-collections": "^v3.0.0", - "purescript-parallel": "^v6.0.0", - "purescript-prelude": "^v6.0.0", - "purescript-react-basic-hooks": "^v8.0.0", - "purescript-refs": "^v6.0.0", - "purescript-tailrec": "^v6.0.0", - "purescript-transformers": "^v6.0.0", - "purescript-tuples": "^v7.0.0", - "purescript-unsafe-reference": "^v5.0.0" - } -} diff --git a/docs/architecture.md b/docs/architecture.md new file mode 100644 index 0000000..63b9bbf --- /dev/null +++ b/docs/architecture.md @@ -0,0 +1,107 @@ +# Halo architecture + +This document describes the ownership and safety invariants that maintainers must preserve. For public usage, start with the [README](../README.md) and [guide](guide.md). + +## Application effects cross one boundary + +Halo keeps application logic in an application monad `m`, commonly an `AppM` built on `ReaderT environment Aff`. `component` and `useHalo` receive a natural transformation in one direction: + +```purescript +m ~> Aff +``` + +`HaloM props state action m` is a `ReaderT` over an internal execution record in `Aff`. Standard `lift` first checks that the execution still owns a current root, then invokes the root's captured interpreter. Derived `MonadEffect`, `MonadAff`, `MonadAsk`, `MonadTell`, and `MonadThrow` capabilities all pass through `m` and therefore use the same fence. Halo component state remains the separate `MonadState state` capability. + +The interpreter must return the owned `Aff` computation. An interpreter that detaches work with `launchAff_` moves that work outside Halo's cancellation boundary. + +## React delegates ownership to the runtime + +[`React.Halo.Component`](../src/React/Halo/Component.purs) computes initial state from the initial props and delegates to `useHalo`. The renderer receives current props, Halo state, its coherent immutable task view, and an action dispatcher. + +[`React.Halo.Hook`](../src/React/Halo/Hook.purs) creates one internal runtime for the hook instance and connects it to React effects: + +1. synchronize the latest interpreter, handlers, error callback, and React state setter; +2. activate the runtime and return synchronous deactivation as effect cleanup; and +3. publish prop changes to the runtime. + +The hook returns current `state`, an immutable task-authority `tasks` view, and `dispatch`. State and task view are published through one React setter as a coherent snapshot. [`React.Halo.Internal.Runtime`](../src/React/Halo/Internal/Runtime.purs) owns fibers, activation scopes, task authority, subscriptions, state fencing, and error routing. + +## Each activation has a generation + +An active runtime holds one scope with a unique generation, an active flag, and maps for handler roots, component forks, task authority, generic cleanup, and subscriptions. Activation is idempotent while that scope is current. Heterogeneous task-slot bindings persist separately for the runtime lifetime; active authority does not. + +Deactivation marks the scope inactive and clears it from the runtime before foreign cleanup or Aff cancellation begins. A later activation creates fresh maps and a new generation. Currency checks require both an active matching generation and a live root owner, so work retained from an earlier generation cannot affect a reactivated component. + +This generation boundary models React development StrictMode's setup-cleanup-setup sequence. `onActivate` runs once for every actual activation; cleanup fences the earlier generation before the replayed activation starts. + +## Handlers and forks are roots + +Every `onActivate`, `onPropsChange`, and `onAction` invocation starts an independently owned handler root. A new handler reads the current interpreter and latest handlers from the runtime. Preparation creates its owner and gated fiber; the runtime records the root before opening the gate, so immediate completion cannot race registration. + +`fork` creates another activation-owned root with an opaque `ForkId`. It has its own liveness fence and may outlive the handler that launched it. The fork inherits the launching root's interpreter snapshot, even if hook synchronization supplied a newer interpreter before the call to `fork`. Unrelated handlers started after synchronization use the newer interpreter. + +Root completion removes only that root's current map entry. IDs are fresh within the runtime, so stale completion cannot remove newer work. + +Managed task policies use the same fork map and root ownership rather than a separate coordination subsystem. A `Task.Slot` combines a type-level brand with a canonical lens. First use registers an erased binding that can inspect and normalize that focus without retaining a body, input, or fork handle. Temporary semantic probes verify that one brand maps to one focus and one focus to one brand; probes are never published. A collision throws in the calling root's existing error context before state mutation or cancellation. + +Activation authority maps a registered slot brand to an exact token containing runtime identity, activation generation, and `ForkId`. In one synchronous transaction the runtime reconciles registered slots, claims authority, fences a superseded root, prepares and records the replacement behind a gate, publishes state and view, requests old cancellation, and opens the new gate. The task body inherits the launching root's interpreter. + +`Task.State` is freely copyable and does not itself prove ownership. `Task.View` is an immutable pair of the published state snapshot and authority map. Slot-aware projection reports `Active` only when the canonical focus and authority contain the exact token; copied, stale, cross-slot, and cross-runtime active values report `Idle`. + +Every generic `MonadState` write reconciles registered bindings before publication. Preserving the exact token is ordinary. Replacing it with correctly branded idle or terminal state removes/fences authority while preserving the requested value. Foreign or stale active state is normalized to branded idle and can never supply a fork to cancel. Typed completion and unexpected failure use exact canonical-focus and authority checks. + +Debounce timing remains private: an owned Aff timer precedes the body in the same managed root, and both phases project `Active`. A typed `Either` completion removes authority and stores `Failed` or `Succeeded` atomically. An unexpected current failure clears the exact run to `Idle` before existing `ForkError` routing. + +## Fences precede cancellation + +Cancellation is cooperative, but ownership loss is synchronous. + +For explicit `kill`, the runtime removes the fork from tracking, fences its owner, requests Aff cancellation, and waits for the fiber and its Aff finalizers before returning. An unknown or completed `ForkId` is a no-op. + +React deactivation cannot wait asynchronously. It invalidates the scope; takes all tracked roots, generic cleanup, and subscriptions; and fences every root. Activation authority is cleared and persistent bindings normalize active task state to `Idle` in the runtime state without calling React's setter during cleanup. Every synchronous cleanup is attempted before cancellation is requested for handler, fork, and task fibers. Cleanup failures are reported only after the runtime has attempted the rest of the cleanup work. + +If deactivation normalized task state, the next activation publishes that runtime state through the latest React setter before starting `onActivate`. Terminal task outcomes have no active root and persist. This ordering keeps StrictMode replay state coherent without adding an asynchronous deactivation callback. + +The fences protect two important boundaries: + +- `MonadState` may still compute a stale operation's return value, but it cannot update stored state or call React's state setter. +- A later `lift` from a stale root fails with Halo's internal cancellation error before invoking `m ~> Aff`. Catching the initial Aff cancellation therefore cannot start a newly lifted application effect. + +Capabilities that create or remove forks, task roots, cleanup, and subscriptions also check currency. Cancellation cannot undo an external effect that already happened inside an application computation; application writes must still use appropriate idempotency or retry semantics. + +## Synchronous cleanup stays activation-scoped + +Generic cleanup and emitter subscription cleanup use separate activation maps. `registerCleanup` stores an `Effect Unit`; `releaseCleanup` removes it before invocation. Deactivation takes both maps and attempts each disposer independently, so one throw cannot block another disposer or root cancellation. Deactivation failures share `DeactivationError`, but cross-category cleanup ordering is not a public contract. + +Cleanup IDs are runtime-fresh and a release consults only the current scope. An ID or stale root retained from one StrictMode activation therefore cannot remove resources from another. + +## Subscriptions close over their activation + +The local [`Emitter`](../src/React/Halo/Subscription.purs) registers an `Effect` callback and returns a synchronous cleanup. The scope tracks that cleanup by `SubscriptionId`. Manual unsubscription removes the entry before running cleanup, which prevents a throwing cleanup from being retried during deactivation. + +Deactivation takes the complete subscription map and attempts each cleanup independently. A retained emitter callback still dispatches through its original scope; the generation check rejects it after deactivation, including after StrictMode reactivation. + +## Parallel branches share ownership + +`HaloAp` is the direct parallel counterpart to `HaloM`: it changes the internal `ReaderT` result from `Aff` to `ParAff` without creating another ownership model. Parallel branches share one root owner, activation scope, error context, and interpreter snapshot. The surrounding computation waits for the branches when it returns to `HaloM`. + +Concurrent Halo state writes have nondeterministic ordering and can overwrite one another. Prefer running independent application reads in parallel, combining their results, and committing Halo state once. + +## Errors use the current reporting callback + +Each root carries the context assigned at launch: `ActivationError`, `PropsChangeError previousProps`, `ActionError action`, or `ForkError id`. Managed task bodies use `ForkError` because they are component-owned roots without separate public run identity. An unexpected failure is reported only while that root and scope are still current. The runtime reads the latest `onError` callback at reporting time, so a render can update reporting without changing an already-running root's interpreter. + +Subscription cleanup failures use `DeactivationError`. Halo-initiated cancellation and stale-lift failures are suppressed because the owner has already been fenced. + +## Tests protect the invariant boundaries + +The deterministic runtime tests exercise ownership without mounting a real DOM fixture: + +- [`RuntimeSpec`](../test/Test/Halo/RuntimeSpec.purs) covers AppM interpretation, handler and fork interpreter snapshots, the stale-lift fence, and direct parallel execution. +- [`ScopeHandlerSpec`](../test/Test/Halo/ScopeHandlerSpec.purs) covers activation generations, StrictMode reactivation, props, handler and fork ownership, explicit kill, finalizer waiting, and stale capability/state rejection. +- [`SubscriptionErrorSpec`](../test/Test/Halo/SubscriptionErrorSpec.purs) covers generic and subscription cleanup isolation, manual release, stale activation IDs and emitter callbacks, error contexts, and latest error-handler selection. +- [`TaskSpec`](../test/Test/Halo/TaskSpec.purs) covers branded slots, view projection, collision detection, state-copy and stale-snapshot reconciliation, cross-runtime authority, policies, atomic claims, supersession and reset, private debounce scheduling, stale effect fences, two-slot deactivation normalization, current setters, and inherited interpreters. +- [`DocExamples`](../test/Test/Halo/DocExamples.purs) compile-checks the complete component, hook, AppM, and task example. +- [`GuideExamples`](../test/Test/Halo/GuideExamples.purs) compile-checks the guide's task, parallel, subscription, and cleanup examples. + +[`test/Main.purs`](../test/Main.purs) runs the full behavioral suite. Preserve these deterministic boundaries when changing the runtime; add a focused regression beside the invariant it protects. diff --git a/docs/guide.md b/docs/guide.md new file mode 100644 index 0000000..5ea3be2 --- /dev/null +++ b/docs/guide.md @@ -0,0 +1,48 @@ +# Halo guide + +Halo connects a React entry point to typed actions, component state, and application effects. Begin with the entry point your component needs, then add stronger ownership only when an interaction requires it. + +## Start here + +- Use [`Halo.component`](guide/getting-started.md#use-component-for-a-complete-component) when Halo owns the complete component. +- Use [`Halo.useHalo`](guide/getting-started.md#use-usehalo-with-other-hooks) when the render function also uses other hooks. + +The [getting-started chapter](guide/getting-started.md) builds both forms from the React boundary inward: initial state, rendering, dispatch, handlers, AppM, and error reporting. + +## Choose the next chapter + +### [Actions, effects, and state](guide/actions-and-state.md) + +Use this chapter to answer: + +- How does `dispatch` reach `onAction`? +- How do I run AppM logic with `lift`? +- How do overlapping handlers affect state? +- How do I read current props or run independent effects in parallel? + +### [Managed work](guide/managed-work.md) + +Use this chapter to choose among handler-owned work, tasks, and forks: + +| Requirement | Mechanism | +|---|---| +| Work belongs to one dispatched action | handler | +| Rendering needs typed lifecycle state | task | +| Work must outlive its launching handler | fork | +| Cancellation must await finalizers | `Task.reset` or `Halo.kill` | + +### [Lifecycle and resources](guide/lifecycle-and-resources.md) + +Use this chapter for activation, StrictMode replay, subscriptions, cleanup, and unexpected errors. + +```text +component or useHalo + └─ action handler + ├─ ordinary HaloM work + ├─ managed task + └─ component-owned fork +``` + +Every handler, task, fork, subscription, and registered cleanup belongs to one React activation. Deactivation fences that activation before cleanup and cancellation requests begin. + +Maintainers changing these guarantees should also read the [runtime architecture](architecture.md). diff --git a/docs/guide/actions-and-state.md b/docs/guide/actions-and-state.md new file mode 100644 index 0000000..edbfd46 --- /dev/null +++ b/docs/guide/actions-and-state.md @@ -0,0 +1,111 @@ +# Actions, effects, and state + +A dispatched action starts an independent handler in the current React activation. Handlers can read current state and props, update state, and lift application logic. + +## Dispatch a typed action + +Keep UI events in an action ADT rather than calling asynchronous logic from rendering: + +```purescript +data Action + = NameChanged String + | Save + +render { dispatch } = + R.input + { onChange: handler targetValue (dispatch <<< NameChanged) + , value: "" + } +``` + +Each call to `dispatch` starts `onAction` synchronously. Dispatch while the component is inactive is ignored. + +## Handle actions independently + +Use `defaultHandlers` when only some lifecycle callbacks matter: + +```purescript +handlers = Halo.defaultHandlers + { onAction = case _ of + NameChanged name -> + modify_ _ { name = name } + + Save -> + saveCurrentForm + } +``` + +Handlers overlap. A long-running `Save` does not block a later `NameChanged`. If later actions must cancel or supersede work, use a [managed task or fork](managed-work.md) rather than relying on handler ordering. + +## Lift application effects + +Application logic stays in AppM and enters Halo through standard transformer `lift`: + +```purescript +saveCurrentForm = do + form <- gets _.form + result <- lift (Form.save form) + modify_ _ { saveResult = Just result } +``` + +Every handler captures the interpreter current when it starts. A later React render may supply a newer interpreter for new handlers, but it does not change one already running. + +## Update current state + +`HaloM` has `MonadState state`, so normal state operations are available: + +```purescript +name <- gets _.name +modify_ _ { submittedName = Just name } +``` + +State operations use the state current at that operation. Avoid restoring a whole snapshot after asynchronous work: + +```purescript +-- Avoid: this can overwrite a newer action's changes. +old <- get +result <- lift (save old.form) +put (old { result = Just result }) +``` + +Capture only the effect input, then update current state: + +```purescript +form <- gets _.form +result <- lift (save form) +modify_ _ { result = Just result } +``` + +This is especially important because action handlers, tasks, and forks may overlap. + +## Read current and previous props + +`onPropsChange` receives the previous props. `getProps` reads the current props: + +```purescript +handlers = Halo.defaultHandlers + { onPropsChange = \previous -> do + current <- Halo.getProps + synchronize previous current + } +``` + +Capture props before waiting when the work must use one render's value. Otherwise, a later `getProps` intentionally observes newer props. + +## Run independent effects in parallel + +`HaloM` has a direct `Parallel` instance. Run independent application reads in parallel, then update component state once: + +```purescript +loadDashboard = do + Tuple profile feed <- sequential ado + profile <- parallel (lift Profile.load) + feed <- parallel (lift Feed.load) + in Tuple profile feed + + modify_ _ { profile = profile, feed = feed } +``` + +Parallel branches share one root, activation, error context, and interpreter snapshot. Concurrent component-state writes have nondeterministic ordering, so prefer combining results before one update. + +Parallel work is lexical: the surrounding computation waits for every branch. Use a [fork](managed-work.md#use-a-fork-for-an-independent-process) when work must continue beyond its launching handler. diff --git a/docs/guide/getting-started.md b/docs/guide/getting-started.md new file mode 100644 index 0000000..ab2b4f4 --- /dev/null +++ b/docs/guide/getting-started.md @@ -0,0 +1,143 @@ +# Getting started + +Halo has two React entry points. Choose one first; their action, state, and application-effect model is otherwise the same. + +## Use `component` for a complete component + +`component` creates a React component from one Halo specification: + +```purescript +loadButton :: Env -> Component Props +loadButton env = + Halo.component "LoadButton" (runAppM env) + { initialState: \_ -> initialState + , handlers + , onError + , render + } +``` + +The specification supplies: + +- initial state derived from the initial props; +- action handlers; +- unexpected-error reporting; and +- a renderer receiving `{ props, state, tasks, dispatch }`. + +Later prop changes do not recreate state. They start `onPropsChange` instead. + +## Use `useHalo` with other hooks + +`useHalo` fits the same runtime into a component that owns its render function: + +```purescript +halo <- Halo.useHalo (runAppM env) + { props + , initialState + , handlers + , onError + } + +pure $ render + { props + , state: halo.state + , tasks: halo.tasks + , dispatch: halo.dispatch + } +``` + +The hook returns current state, an immutable managed-task view, and synchronous dispatch. Use ordinary React hooks alongside it as needed. + +## Define state and actions + +State contains the values used for rendering. An action ADT describes events that rendering can send to Halo: + +```purescript +type Props = { title :: String } + +type State = + { greeting :: Maybe String + } + +initialState :: State +initialState = + { greeting: Nothing + } + +data Action = LoadGreeting +``` + +## Render state and dispatch actions + +Rendering is ordinary `react-basic` code. Calling `dispatch` starts `handlers.onAction` in the active component scope: + +```purescript +render { props, state, dispatch } = + R.div_ + [ R.text props.title + , R.button + { onClick: capture_ (dispatch LoadGreeting) + , children: [ R.text "Load" ] + } + , R.text $ fromMaybe "Not loaded" state.greeting + ] +``` + +Dispatch is synchronous; the handler it starts may continue asynchronously. + +## Handle the action + +Start with `defaultHandlers` and replace only the callbacks the component needs: + +```purescript +handlers :: Halo.Handlers Props State Action AppM +handlers = Halo.defaultHandlers + { onAction = case _ of + LoadGreeting -> do + greeting <- lift loadGreeting + modify_ _ { greeting = Just greeting } + } +``` + +`HaloM` supplies component state and props. Standard transformer `lift` runs application logic through the interpreter passed to `component` or `useHalo`. + +## Define the application boundary + +Application services remain in the application's own monad: + +```purescript +type Env = + { loadGreeting :: Aff String + } + +newtype AppM a = AppM (ReaderT Env Aff a) + +runAppM :: Env -> AppM ~> Aff +runAppM env (AppM program) = runReaderT program env + +loadGreeting :: AppM String +loadGreeting = AppM do + env <- ask + liftAff env.loadGreeting +``` + +The component computation type makes both layers explicit: + +```purescript +type UI a = Halo.HaloM Props State Action AppM a +``` + +The interpreter must return the `Aff` that performs the work. Do not detach it with `launchAff_`; Halo can own and cancel only the returned computation. + +## Report unexpected errors + +Both entry points require a synchronous error callback: + +```purescript +onError _ error = + Console.error $ message error +``` + +Expected domain failures should remain typed application values or component state. `onError` is for unexpected exceptions from a current Halo-owned root or synchronous cleanup. + +Next, see [Actions, effects, and state](actions-and-state.md) for overlapping handlers, safe state updates, props changes, and parallel work. diff --git a/docs/guide/lifecycle-and-resources.md b/docs/guide/lifecycle-and-resources.md new file mode 100644 index 0000000..76a287c --- /dev/null +++ b/docs/guide/lifecycle-and-resources.md @@ -0,0 +1,136 @@ +# Lifecycle and resources + +One Halo runtime may pass through multiple React effect activations during development StrictMode. Handlers, forks, tasks, subscriptions, and registered cleanup belong to the activation that created them. + +## Configure lifecycle handlers + +Start with `defaultHandlers` and replace the callbacks the component uses: + +```purescript +handlers = Halo.defaultHandlers + { onActivate = initialize + , onPropsChange = synchronizeProps + , onAction = handleAction + } +``` + +`onActivate` runs for every actual activation: + +```purescript +onActivate = + Task.once initializationSlot initialize +``` + +Development StrictMode may run setup, cleanup, then setup again for one hook instance. Treat activation as repeatable, not as an exactly-once mount event. + +`onPropsChange` receives the previous props; read current props with `getProps`: + +```purescript +onPropsChange previous = do + current <- Halo.getProps + synchronize previous current +``` + +`onAction` runs once for each dispatch in the active scope: + +```purescript +onAction = case _ of + Submitted -> submit + Cancelled -> cancel +``` + +Each invocation is an independent root using the latest handlers and application interpreter supplied to the React boundary. + +## Turn external events into actions + +Create an emitter from registration logic. Registration returns synchronous cleanup for that receiver: + +```purescript +names :: Halo.Emitter String +names = Halo.makeEmitter \emit -> + source.listen emit +``` + +`Emitter` has a `Functor` instance, so map source values into the component action type before subscribing: + +```purescript +actions :: Halo.Emitter Action +actions = NameChanged <$> names + +onActivate = + void $ Halo.subscribe actions +``` + +Mapping changes emitted values without changing source registration or cleanup. Emitters deliberately have no `Applicative` instance because combining event sources would require a synchronization policy such as zip or latest-value. + +Use `subscribeWithId` when normal component flow must unsubscribe early: + +```purescript +subscriptionId <- Halo.subscribeWithId \_ -> actions +Halo.unsubscribe subscriptionId +``` + +Manual unsubscribe removes tracking before running cleanup. Deactivation attempts cleanup for every subscription that remains registered. A retained callback stays bound to its original activation and cannot dispatch into a later StrictMode activation. + +Emitters broadcast actions. They do not provide backpressure, consuming queues, or scheduling policies. + +## Register synchronous cleanup + +Use `registerCleanup` for a synchronous resource that is not an emitter subscription: + +```purescript +cleanupId <- Halo.registerCleanup removeListener +``` + +Release it early when normal component flow no longer needs the resource: + +```purescript +Halo.releaseCleanup cleanupId +``` + +Release removes the entry before invoking it. Unknown and already released IDs are ignored, and a throwing release is not retried during deactivation. + +## Put asynchronous cleanup in an Aff finalizer + +React effect cleanup is synchronous, so Halo intentionally has no asynchronous `onDeactivate` handler. Acquire and release an asynchronous resource inside owned Aff work: + +```purescript +void $ Halo.fork do + liftAff $ Aff.bracket acquire release use +``` + +Deactivation requests cancellation of the fork, which runs its Aff finalizer. React does not wait for that cancellation, so persistence or other required writes should happen during normal application flow rather than depending on unmount. + +## Understand deactivation order + +Deactivation first fences the activation. It then attempts synchronous registered and subscription cleanup before requesting cancellation of handlers, tasks, and forks. + +```purescript +onError DeactivationError error = + reportCleanupFailure error +``` + +One throwing cleanup does not prevent the remaining cleanup or cancellation requests. No ordering between generic and subscription cleanup is part of the API. + +A stale root cannot commit component state, register another Halo capability, or begin a newly lifted application effect after the fence—even if it catches the initial Aff cancellation. + +## Report unexpected errors + +Both React entry points require: + +```purescript +onError :: ErrorContext props action -> Error -> Effect Unit +``` + +Pattern match on the context when reporting needs different metadata: + +```purescript +onError context error = case context of + ActivationError -> report "activation" error + PropsChangeError previous -> reportProps previous error + ActionError action -> reportAction action error + ForkError forkId -> reportFork forkId error + DeactivationError -> report "cleanup" error +``` + +Halo reads the latest callback when an unexpected current failure is reported. Expected domain failures belong in application values, actions, or task outcomes. Halo-initiated cancellation is suppressed after its root is fenced. diff --git a/docs/guide/managed-work.md b/docs/guide/managed-work.md new file mode 100644 index 0000000..deaed7d --- /dev/null +++ b/docs/guide/managed-work.md @@ -0,0 +1,158 @@ +# Managed work + +Leave work in its action handler when no other action needs to identify it and rendering does not need a typed lifecycle. Add a task for renderable outcomes or a fork for an independent component process. + +## Start with handler-owned work + +A handler is already owned and cancelled by its React activation: + +```purescript +Refresh -> do + account <- lift Account.load + modify_ _ { account = Just account } +``` + +No fork is needed merely because the application effect is asynchronous. + +## Use a task for typed lifecycle state + +A task field retains `Idle`, `Active`, a typed failure, or a typed result in component state: + +```purescript +type State = + { search :: Task.State SearchError Results + , query :: String + } + +searchSlot :: Task.Slot "search" State SearchError Results +searchSlot = Task.slot (Proxy :: Proxy "search") + +initialState = + { search: Task.idle searchSlot + , query: "" + } +``` + +`Task.slot` uses its type-level label as both record field and identity. Use `slotAt` only for a nested or custom lawful focus: + +```purescript +nestedSearchSlot = + Task.slotAt (Proxy :: Proxy "nestedSearch") + (tasksLens <<< searchLens) +``` + +One slot name must identify one focus for the runtime lifetime. Reusing a name for another lens—or giving one focus two names—is invalid and fails on first use before state mutation or cancellation: + +```purescript +-- Invalid if `searchSlot` already names another focus. +duplicate = Task.slotAt (Proxy :: Proxy "search") otherLens +``` + +A task body is ordinary `HaloM` returning `Either error result`: + +```purescript +Search query -> Task.supersede searchSlot do + modify_ _ { query = query } + lift (Search.run query) +``` + +A renderer receives `tasks :: Task.View State` beside component state: + +```purescript +case Task.toStatus tasks searchSlot of + Task.Idle -> renderPrompt + Task.Active -> renderSpinner + Task.Failed error -> renderError error + Task.Succeeded results -> renderResults results +``` + +`Task.toMaybe tasks slot` returns only a successful result. `Task.isActive tasks slot` covers both a debounce timer and an executing body. The status prisms can inspect a projected status: + +```purescript +result = preview Task._Succeeded (Task.toStatus tasks searchSlot) +``` + +State and task view come from one coherent render snapshot. `Task.State` is freely copyable, but a copied, stale, cross-slot, or cross-runtime active value has no matching authority and projects `Idle`; it cannot cross-cancel or commit over current work. + +## Choose a task policy + +Use `once` for initialization that remains terminal until reset: + +```purescript +Task.once initializationSlot initialize +``` + +Use `startIfInactive` when another invocation should run after either success or typed failure, but not while work is active: + +```purescript +Task.startIfInactive saveSlot save +``` + +Use `supersede` when every new invocation should become authoritative immediately: + +```purescript +Task.supersede searchSlot (search query) +``` + +Use `debounce` for trailing-edge latest-wins interaction: + +```purescript +Task.debounce searchSlot (Milliseconds 250.0) (search query) +``` + +Its private timer and body both render as `Active`. A new invocation cancels either phase. + +Use `reset` to clear terminal state or cancel active work: + +```purescript +Task.reset searchSlot +``` + +Reset publishes `Idle`, fences active work, and waits for its Aff finalizers. Supersession fences old work immediately but does not wait for its finalizers before starting the replacement. + +Expected failures belong in `Either`. An unexpected exception returns the matching current task to `Idle` and follows Halo's `ForkError` reporting path. Cancellation is neither a typed failure nor an unexpected error. + +Put retry policy in AppM and lift the retrying computation. Halo does not add retry, timestamps, or a generic scheduler to task state. Task state is component-owned result storage, not a global cache, and no computation or input is retained for reruns. + +## Use a fork for an independent process + +A fork has its own component-owned identity and may outlive the handler that starts it. Tasks and forks inherit the application interpreter captured by the handler that launches them: + + +```purescript +startSynchronization = do + fiber <- Halo.fork synchronize + modify_ _ { synchronization: Just fiber } +``` + +Retain its `ForkId` when another action must cancel it: + +```purescript +cancelSynchronization = do + current <- gets _.synchronization + traverse_ Halo.kill current + modify_ _ { synchronization = Nothing } +``` + +`kill` removes and fences the fork synchronously, then waits for Aff cancellation and finalizers. Killing an unknown or completed ID does nothing. + +Use an Aff finalizer for asynchronous resource release inside owned work: + +```purescript +connectionProcess = Halo.fork do + liftAff $ Aff.finally useConnection closeConnection +``` + +React cannot await deactivation cleanup, but the ownership fence prevents a cancelled finalizer from committing Halo state or beginning another lifted application effect. + +## Choose by observable behavior + +| Requirement | Use | +|---|---| +| One action owns the result | handler | +| Rendering needs typed lifecycle state | task | +| A newer call replaces an older call | `supersede` or `debounce` | +| Work continues after its handler returns | fork | +| Cancellation must await finalizers | `reset` or `kill` | + +Cancellation cannot retract an HTTP request, storage write, callback, or log that already happened. External writes still need appropriate idempotency or retry semantics. diff --git a/package-lock.json b/package-lock.json index 197dde4..46d55d6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,50 +1,123 @@ { "name": "purescript-react-halo", - "version": "1.0.0", - "lockfileVersion": 2, + "version": "4.0.0", + "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "purescript-react-halo", - "version": "1.0.0", - "license": "ISC", + "version": "4.0.0", + "license": "BSD-3-Clause", "devDependencies": { - "bower": "^1.8.14", - "pulp": "^16.0.2", - "purescript": "^0.15.4", - "purescript-psa": "^0.8.2", - "purs-tidy": "^0.9.0", - "rimraf": "^3.0.2", - "spago": "^0.20.9" + "purescript": "0.15.16", + "spago": "1.0.4" } }, "node_modules/@gar/promisify": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/@isaacs/cliui": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-9.0.0.tgz", + "integrity": "sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@isaacs/fs-minipass/node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-4.0.1.tgz", + "integrity": "sha512-vAkI715yhnmiPupY+dq+xenu5Tdf2TBQ66jLvBIcCddtz+5Q8LbMKaf9CIJJreez8fQ8fgaY+RaywQx8RJIWpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "4.0.0", + "run-parallel": "^1.2.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-4.0.0.tgz", + "integrity": "sha512-ctr6bByzksKRCV0bavi8WoQevU6plSp2IkllIsEqaiKe2mwNNnaluhnRhcsgGZHrrHk57B3lf95MkLMO3STYcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-3.0.1.tgz", + "integrity": "sha512-nIh/M6Kh3ZtOmlY00DaUYB4xeeV6F3/ts1l29iwl3/cfyY/OuCfUx+v08zgx8TKPTifXRcjjqVQ4KB2zOYSbyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "4.0.1", + "fastq": "^1.15.0" + }, + "engines": { + "node": ">=18.18.0" + } }, "node_modules/@npmcli/fs": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz", - "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.2.tgz", + "integrity": "sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==", "dev": true, + "license": "ISC", "dependencies": { - "@gar/promisify": "^1.0.1", + "@gar/promisify": "^1.1.3", "semver": "^7.3.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/@npmcli/move-file": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", - "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-2.0.1.tgz", + "integrity": "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==", + "deprecated": "This functionality has been moved to @npmcli/fs", "dev": true, + "license": "MIT", "dependencies": { "mkdirp": "^1.0.4", "rimraf": "^3.0.2" }, "engines": { - "node": ">=10" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/@npmcli/move-file/node_modules/mkdirp": { @@ -52,6 +125,7 @@ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true, + "license": "MIT", "bin": { "mkdirp": "bin/cmd.js" }, @@ -59,45 +133,31 @@ "node": ">=10" } }, - "node_modules/@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "node_modules/@npmcli/move-file/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, "bin": { - "acorn": "bin/acorn" + "rimraf": "bin.js" }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-node": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz", - "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==", - "dev": true, - "dependencies": { - "acorn": "^7.0.0", - "acorn-walk": "^7.0.0", - "xtend": "^4.0.2" + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "node_modules/@tootallnate/once": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.1.tgz", + "integrity": "sha512-HqmEUIGRJ5fSXchkVgR5F7qn48bDBzv0kWj/Kfu5e6uci4UlEeng4331LnBkWffb++Ei3FOVLxo8JJWMFBDMeQ==", "dev": true, + "license": "MIT", "engines": { - "node": ">=0.4.0" + "node": ">= 10" } }, "node_modules/agent-base": { @@ -105,6 +165,7 @@ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "dev": true, + "license": "MIT", "dependencies": { "debug": "4" }, @@ -113,13 +174,12 @@ } }, "node_modules/agentkeepalive": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.2.1.tgz", - "integrity": "sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz", + "integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==", "dev": true, + "license": "MIT", "dependencies": { - "debug": "^4.1.0", - "depd": "^1.1.2", "humanize-ms": "^1.2.1" }, "engines": { @@ -131,6 +191,7 @@ "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", "dev": true, + "license": "MIT", "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" @@ -139,38 +200,30 @@ "node": ">=8" } }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, + "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "type-fest": "^0.21.3" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", - "dev": true, "engines": { - "node": ">=4" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, + "license": "MIT", "engines": { - "node": ">=6" + "node": ">=8" } }, "node_modules/ansi-styles": { @@ -178,6 +231,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^1.9.0" }, @@ -189,150 +243,49 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true + "dev": true, + "license": "ISC" }, - "node_modules/arch": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", - "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] + "license": "Python-2.0" }, "node_modules/asn1": { "version": "0.2.6", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", "dev": true, + "license": "MIT", "dependencies": { "safer-buffer": "~2.1.0" } }, - "node_modules/asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", - "dev": true, - "dependencies": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" - } - }, - "node_modules/asn1.js/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/assert": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", - "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", - "dev": true, - "dependencies": { - "object-assign": "^4.1.1", - "util": "0.10.3" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/assert/node_modules/inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA==", - "dev": true - }, - "node_modules/assert/node_modules/util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha512-5KiHfsmkqacuKjkRkdV7SsfDJ2EGiPsK92s2MhNSY0craxjTdKTtqKsJaCWp4LW33ZZ0OPUv1WO/TFvNQRiQxQ==", - "dev": true, - "dependencies": { - "inherits": "2.0.1" - } - }, - "node_modules/async": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", - "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", - "dev": true, - "dependencies": { - "lodash": "^4.17.14" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true - }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true, + "license": "MIT", "engines": { - "node": "*" + "node": ">=8" } }, - "node_modules/aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", - "dev": true - }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] + "license": "MIT" }, "node_modules/bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "tweetnacl": "^0.14.3" } @@ -341,535 +294,191 @@ "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "node_modules/bower": { - "version": "1.8.14", - "resolved": "https://registry.npmjs.org/bower/-/bower-1.8.14.tgz", - "integrity": "sha512-8Rq058FD91q9Nwthyhw0la9fzpBz0iwZTrt51LWl+w+PnJgZk9J+5wp3nibsJcIUPglMYXr4NRBaR+TUj0OkBQ==", "dev": true, - "bin": { - "bower": "bin/bower" - }, - "engines": { - "node": ">=0.10.0" - } + "license": "MIT" }, "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", + "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", - "dev": true - }, - "node_modules/browser-pack": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.1.0.tgz", - "integrity": "sha512-erYug8XoqzU3IfcU8fUgyHqyOXqIE4tUTTQ+7mqUjQlvnXkOO6OlT9c/ZoJVHYoAaqGxr09CN53G7XIsO4KtWA==", + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, + "license": "MIT", "dependencies": { - "combine-source-map": "~0.8.0", - "defined": "^1.0.0", - "JSONStream": "^1.0.3", - "safe-buffer": "^5.1.1", - "through2": "^2.0.0", - "umd": "^3.0.0" + "fill-range": "^7.1.1" }, - "bin": { - "browser-pack": "bin/cmd.js" + "engines": { + "node": ">=8" } }, - "node_modules/browser-resolve": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-2.0.0.tgz", - "integrity": "sha512-7sWsQlYL2rGLy2IWm8WL8DCTJvYLc/qlOnsakDac87SOoCd16WLsaAMdCiAqsTNHIe+SXfaqyxyo6THoWqs8WQ==", + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true, - "dependencies": { - "resolve": "^1.17.0" - } + "license": "MIT" }, - "node_modules/browserify": { - "version": "16.5.2", - "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.5.2.tgz", - "integrity": "sha512-TkOR1cQGdmXU9zW4YukWzWVSJwrxmNdADFbqbE3HFgQWe5wqZmOawqZ7J/8MPCwk/W8yY7Y0h+7mOtcZxLP23g==", + "node_modules/buildcheck": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/buildcheck/-/buildcheck-0.0.7.tgz", + "integrity": "sha512-lHblz4ahamxpTmnsk+MNTRWsjYKv965MwOrSJyeD588rR3Jcu7swE+0wN5F+PbL5cjgu/9ObkhfzEPuofEMwLA==", "dev": true, - "dependencies": { - "assert": "^1.4.0", - "browser-pack": "^6.0.1", - "browser-resolve": "^2.0.0", - "browserify-zlib": "~0.2.0", - "buffer": "~5.2.1", - "cached-path-relative": "^1.0.0", - "concat-stream": "^1.6.0", - "console-browserify": "^1.1.0", - "constants-browserify": "~1.0.0", - "crypto-browserify": "^3.0.0", - "defined": "^1.0.0", - "deps-sort": "^2.0.0", - "domain-browser": "^1.2.0", - "duplexer2": "~0.1.2", - "events": "^2.0.0", - "glob": "^7.1.0", - "has": "^1.0.0", - "htmlescape": "^1.1.0", - "https-browserify": "^1.0.0", - "inherits": "~2.0.1", - "insert-module-globals": "^7.0.0", - "JSONStream": "^1.0.3", - "labeled-stream-splicer": "^2.0.0", - "mkdirp-classic": "^0.5.2", - "module-deps": "^6.2.3", - "os-browserify": "~0.3.0", - "parents": "^1.0.1", - "path-browserify": "~0.0.0", - "process": "~0.11.0", - "punycode": "^1.3.2", - "querystring-es3": "~0.2.0", - "read-only-stream": "^2.0.0", - "readable-stream": "^2.0.2", - "resolve": "^1.1.4", - "shasum": "^1.0.0", - "shell-quote": "^1.6.1", - "stream-browserify": "^2.0.0", - "stream-http": "^3.0.0", - "string_decoder": "^1.1.1", - "subarg": "^1.0.0", - "syntax-error": "^1.1.1", - "through2": "^2.0.0", - "timers-browserify": "^1.0.1", - "tty-browserify": "0.0.1", - "url": "~0.11.0", - "util": "~0.10.1", - "vm-browserify": "^1.0.0", - "xtend": "^4.0.0" - }, - "bin": { - "browserify": "bin/cmd.js" - }, + "optional": true, "engines": { - "node": ">= 0.8" + "node": ">=10.0.0" } }, - "node_modules/browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", "dev": true, + "license": "MIT", "dependencies": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/browserify-cache-api": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/browserify-cache-api/-/browserify-cache-api-3.0.2.tgz", - "integrity": "sha512-14YNbboSgSHY5QNZSLwlGYB7OuBuXS7gMyR2gfBjdS4JYcWB9BqyKhraQG/VW2W5ZhjkC/C8LZ38sP3bmbmeNA==", + "node_modules/byline": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/byline/-/byline-5.0.0.tgz", + "integrity": "sha512-s6webAy+R4SR8XVuJWt2V2rGvhnrhxN+9S15GNuTK3wKPOXFF6RNc+8ug2XhH+2s4f+uudG4kUVYmYOQWL2g0Q==", "dev": true, - "dependencies": { - "async": "^2.6.4", - "through2": "^2.0.0", - "xtend": "^4.0.0" + "license": "MIT", + "engines": { + "node": ">=0.10.0" } }, - "node_modules/browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "node_modules/cacache": { + "version": "11.3.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.3.tgz", + "integrity": "sha512-p8WcneCytvzPxhDvYp31PD039vi77I12W+/KfR9S8AZbaiARFBCpsPJS+9uhWfeBfeAtW7o/4vt3MUqLkbY6nA==", "dev": true, + "license": "ISC", "dependencies": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" } }, - "node_modules/browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, + "license": "MIT", "dependencies": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" } }, - "node_modules/browserify-incremental": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/browserify-incremental/-/browserify-incremental-3.1.1.tgz", - "integrity": "sha512-PrFwOzLEdy27VRXK2uGjmjLq1aROBG7QoQq3eKanmm6Q8vuzT0ZNFCORHh3yJgNQQooXA9tOizGv4vCOmhrvRQ==", + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", "dev": true, - "dependencies": { - "browserify-cache-api": "^3.0.0", - "JSONStream": "^0.10.0", - "through2": "^2.0.0", - "xtend": "^4.0.0" - }, - "bin": { - "browserifyinc": "bin/cmd.js" - }, - "peerDependencies": { - "browserify": "*" - } + "license": "ISC" }, - "node_modules/browserify-incremental/node_modules/jsonparse": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-0.0.5.tgz", - "integrity": "sha512-fw7Q/8gFR8iSekUi9I+HqWIap6mywuoe7hQIg3buTVjuZgALKj4HAmm0X6f+TaL4c9NJbvyFQdaI2ppr5p6dnQ==", + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", "dev": true, - "engines": [ - "node >= 0.2.0" - ] + "license": "MIT", + "engines": { + "node": ">=6" + } }, - "node_modules/browserify-incremental/node_modules/JSONStream": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-0.10.0.tgz", - "integrity": "sha512-8XbSFFd43EG+1thjLNFIzCBlwXti0yKa7L+ak/f0T/pkC+31b7G41DXL/JzYpAoYWZ2eCPiu4IIqzijM8N0a/w==", + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", "dev": true, + "license": "MIT", "dependencies": { - "jsonparse": "0.0.5", - "through": ">=2.2.7 <3" - }, - "bin": { - "JSONStream": "index.js" + "restore-cursor": "^3.1.0" }, "engines": { - "node": "*" + "node": ">=8" } }, - "node_modules/browserify-rsa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", - "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, + "license": "MIT", "dependencies": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - } - }, - "node_modules/browserify-sign": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", - "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", - "dev": true, - "dependencies": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.3", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - } - }, - "node_modules/browserify-sign/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "dependencies": { - "pako": "~1.0.5" - } - }, - "node_modules/browserify/node_modules/concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "engines": [ - "node >= 0.8" - ], - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", - "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", - "dev": true, - "dependencies": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", - "dev": true - }, - "node_modules/builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==", - "dev": true - }, - "node_modules/byline": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/byline/-/byline-5.0.0.tgz", - "integrity": "sha512-s6webAy+R4SR8XVuJWt2V2rGvhnrhxN+9S15GNuTK3wKPOXFF6RNc+8ug2XhH+2s4f+uudG4kUVYmYOQWL2g0Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cacache": { - "version": "11.3.3", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.3.tgz", - "integrity": "sha512-p8WcneCytvzPxhDvYp31PD039vi77I12W+/KfR9S8AZbaiARFBCpsPJS+9uhWfeBfeAtW7o/4vt3MUqLkbY6nA==", - "dev": true, - "dependencies": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - } - }, - "node_modules/cacache/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/cached-path-relative": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.1.0.tgz", - "integrity": "sha512-WF0LihfemtesFcJgO7xfOoOcnWzY/QHR4qeDqV44jPU3HTI54+LnfXK3SA27AVVGCdZFgjjFFaqUA9Jx7dMJZA==", - "dev": true - }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", - "dev": true - }, - "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "node_modules/cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==", - "dev": true, - "dependencies": { - "restore-cursor": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" + "color-name": "1.1.3" } }, "node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true, - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/combine-source-map": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", - "integrity": "sha512-UlxQ9Vw0b/Bt/KYwCFqdEwsQ1eL8d1gibiFb7lxQJFdvTgc2hIZi6ugsg+kyhzhPV+QEpUiEIwInIAIrgoEkrg==", - "dev": true, - "dependencies": { - "convert-source-map": "~1.1.0", - "inline-source-map": "~0.6.0", - "lodash.memoize": "~3.0.3", - "source-map": "~0.5.3" - } - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dev": true, - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } + "license": "MIT" }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/concat-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", - "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", "dev": true, "engines": [ - "node >= 6.0" + "node >= 0.8" ], + "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", - "readable-stream": "^3.0.2", + "readable-stream": "^2.2.2", "typedarray": "^0.0.6" } }, - "node_modules/concat-stream/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "node_modules/constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==", - "dev": true - }, - "node_modules/convert-source-map": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", - "integrity": "sha512-Y8L5rp6jo+g9VEPgvqNfEopjTR4OTYct8lXlS8iVQdmnjDvbdbzYe9rjtFCB9egC86JoNCU61WRY+ScjkZpnIg==", - "dev": true - }, "node_modules/copy-concurrently": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", + "deprecated": "This package is no longer supported.", "dev": true, + "license": "ISC", "dependencies": { "aproba": "^1.1.1", "fs-write-stream-atomic": "^1.0.8", @@ -879,72 +488,34 @@ "run-queue": "^1.0.0" } }, - "node_modules/copy-concurrently/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true - }, - "node_modules/create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", - "dev": true, - "dependencies": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - } - }, - "node_modules/create-ecdh/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", "dev": true, - "dependencies": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } + "license": "MIT" }, - "node_modules/create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "node_modules/cpu-features": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.10.tgz", + "integrity": "sha512-9IkYqtX3YHPCzoVg1Py+o9057a3i0fp7S530UWokCSaFVTc7CwXPRiOjRjBQQ18ZCNafx78YfnG+HALxtVmOGA==", "dev": true, + "hasInstallScript": true, + "optional": true, "dependencies": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" + "buildcheck": "~0.0.6", + "nan": "^2.19.0" + }, + "engines": { + "node": ">=10.0.0" } }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -959,6 +530,7 @@ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -969,59 +541,21 @@ "node": ">= 8" } }, - "node_modules/crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "dependencies": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - }, - "engines": { - "node": "*" - } - }, "node_modules/cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha512-NJGVKPS81XejHcLhaLJS7plab0fK3slPh11mESeeDq2W4ZI5kUKK/LRRdVDvjJseojbPB7ZwjnyOybg3Igea/A==", - "dev": true - }, - "node_modules/dash-ast": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/dash-ast/-/dash-ast-1.0.0.tgz", - "integrity": "sha512-Vy4dx7gquTeMcQR/hDkYLGUnwVil6vk4FOOct+djUnHOUWt+zJPJAaRIXaAFkPXtJjvlY7o3rfRu0/3hpnwoUA==", - "dev": true - }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.2.tgz", + "integrity": "sha512-0sVXIohTfLqVIW3kb/0n6IiWF3Ifj5nm2XaSrLq2DI6fKIGa2fYAZdk917rUneaeLVpYfFcyXE2ft0fe3remsA==", "dev": true, - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } + "license": "MIT" }, "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, + "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -1032,187 +566,109 @@ } } }, - "node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/defined": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", - "integrity": "sha512-Y2caI5+ZwS5c3RiNDJ6u53VhQHv+hHKwhkI1iHvceKUHw9Df6EK2zRLfjejRgMuCuxK7PfSWIMwWecceVvThjQ==", - "dev": true - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "node_modules/default-browser": { + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.5.1.tgz", + "integrity": "sha512-m1pAzaJgZ/gssEqlOhJkPJp8Xly7QyW6xcrkUa2KKcDeDSEMP7X8xipU3snUcfisTQx0w1AGae+9UtJSfVnXGw==", "dev": true, + "license": "MIT", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, "engines": { - "node": ">=0.4.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "node_modules/default-browser-id": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.1.tgz", + "integrity": "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==", "dev": true, + "license": "MIT", "engines": { - "node": ">= 0.6" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/deps-sort": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.1.tgz", - "integrity": "sha512-1orqXQr5po+3KI6kQb9A4jnXT1PBwggGl2d7Sq2xsnOeI9GPcE/tGcF9UiSZtZBM7MukY4cAh7MemS6tZYipfw==", + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", "dev": true, - "dependencies": { - "JSONStream": "^1.0.3", - "shasum-object": "^1.0.0", - "subarg": "^1.0.0", - "through2": "^2.0.0" + "license": "MIT", + "engines": { + "node": ">=12" }, - "bin": { - "deps-sort": "bin/cmd.js" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "node_modules/duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", "dev": true, + "license": "MIT", "dependencies": { + "end-of-stream": "^1.0.0", "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" } }, - "node_modules/detective": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.1.tgz", - "integrity": "sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==", + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true, - "dependencies": { - "acorn-node": "^1.8.2", - "defined": "^1.0.0", - "minimist": "^1.2.6" - }, - "bin": { - "detective": "bin/detective.js" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "dependencies": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "node_modules/diffie-hellman/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true, - "engines": { - "node": ">=0.4", - "npm": ">=1.2" - } - }, - "node_modules/duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", - "dev": true, - "dependencies": { - "readable-stream": "^2.0.2" - } - }, - "node_modules/duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", - "dev": true, - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true + "license": "MIT" }, "node_modules/encoding": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "iconv-lite": "^0.6.2" } }, "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", "dev": true, + "license": "MIT", "dependencies": { "once": "^1.4.0" } }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/env-paths": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -1221,47 +677,25 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", - "dev": true - }, - "node_modules/es6-promise": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", - "integrity": "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.0" } }, - "node_modules/events": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-2.1.0.tgz", - "integrity": "sha512-3Zmiobend8P9DjmKAty0Era4jV8oJ0yGYe2nJJAxgymF9+N8F2m0hhZiMoWtcfepExzNKZumFU3ksdQbInGWCg==", - "dev": true, - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "dependencies": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, "node_modules/execa": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/execa/-/execa-2.1.0.tgz", "integrity": "sha512-Y/URAVapfbYy2Xp/gb6A0E7iR8xeqOCXsuuaoMn7A5PzrXUK84E1gyiEfq0wQd/GHA6GsoHWwhNq8anb0mleIw==", "dev": true, + "license": "MIT", "dependencies": { "cross-spawn": "^7.0.0", "get-stream": "^5.0.0", @@ -1277,85 +711,86 @@ "node": "^8.12.0 || >=9.7.0" } }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "node_modules/fastq": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.3.tgz", + "integrity": "sha512-XKv5nnLs6nLF71NgiKJLIZFLkPyIEuOselLG7ujZnGrRfQK8HpvY+WqKhAJUAdLomwVHErVS4LfxFlPq0/FTAw==", "dev": true, - "engines": [ - "node >=0.6.0" - ] - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fast-safe-stringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", - "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", - "dev": true + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } }, "node_modules/figgy-pudding": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", - "dev": true + "deprecated": "This module is no longer supported.", + "dev": true, + "license": "ISC" }, "node_modules/filesize": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/filesize/-/filesize-4.2.1.tgz", "integrity": "sha512-bP82Hi8VRZX/TUBKfE24iiUGsB/sfm2WUrwTQyAzQrhO3V9IhcBBNBXMyzLY5orACxRyYJ3d2HeRVX+eFv4lmA==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">= 0.4.0" } }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/flush-write-stream": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", "dev": true, + "license": "MIT", "dependencies": { "inherits": "^2.0.3", "readable-stream": "^2.3.6" } }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, "engines": { - "node": "*" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, + "license": "ISC", "engines": { - "node": ">= 0.12" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/from2": { @@ -1363,35 +798,47 @@ "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==", "dev": true, + "license": "MIT", "dependencies": { "inherits": "^2.0.1", "readable-stream": "^2.0.0" } }, - "node_modules/fs-minipass": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", - "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "node_modules/fs-extra": { + "version": "11.4.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.4.0.tgz", + "integrity": "sha512-EQsFzMUJkCKGr1ePqlYADkIUmHW1s3ZXr5Yqy6wbGrfUCphpl2maM/kyOIRA2HpP3AaFQTZXD4ldjek+nccddA==", "dev": true, + "license": "MIT", "dependencies": { - "minipass": "^2.6.0" + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" } }, - "node_modules/fs-minipass/node_modules/minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", "dev": true, + "license": "ISC", "dependencies": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" } }, "node_modules/fs-write-stream-atomic": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", "integrity": "sha512-gehEzmPn2nAwr39eay+x3X34Ra+M2QlVUTLhkXPjWdeO8RF9kszk116avgBJM3ZyNHgHXBNx+VmPaFC36k0PzA==", + "deprecated": "This package is no longer supported.", "dev": true, + "license": "ISC", "dependencies": { "graceful-fs": "^4.1.2", "iferr": "^0.1.5", @@ -1403,37 +850,29 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "dev": true, + "license": "ISC" }, - "node_modules/gaze": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", - "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", + "node_modules/fuse.js": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-7.5.0.tgz", + "integrity": "sha512-sQtrEfA+ez/3G0cCZecF70oqpCRttCexYUG4mUrtWL49ULUzUyxokt5kyqwtKzj1270RaKih+hcP3qLcumccow==", "dev": true, - "dependencies": { - "globule": "^1.0.0" - }, + "license": "Apache-2.0", "engines": { - "node": ">= 4.0.0" + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/krisk" } }, - "node_modules/get-assigned-identifiers": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz", - "integrity": "sha512-mBBwmeGTrxEMO4pMaaf/uUEFHnYtwr8FTe8Y/mer4rcV/bye0qGm6pw1bGZFGStxC5O76c5ZAVBGnqHmOaJpdQ==", - "dev": true - }, "node_modules/get-stream": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, + "license": "MIT", "dependencies": { "pump": "^3.0.0" }, @@ -1444,20 +883,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0" - } - }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "dev": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -1473,173 +905,38 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/globule": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.4.tgz", - "integrity": "sha512-OPTIfhMBh7JbBYDpa5b+Q5ptmMWKwcNcFSR/0c6t8V4f3ZAVBEsKNY37QdVqmLRYSMhOUGYrY0QhSoEpzGr/Eg==", - "dev": true, - "dependencies": { - "glob": "~7.1.1", - "lodash": "^4.17.21", - "minimatch": "~3.0.2" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/globule/node_modules/glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/globule/node_modules/minimatch": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", - "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "dev": true - }, - "node_modules/har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "deprecated": "this library is no longer supported", - "dev": true, - "dependencies": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true, - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } + "license": "ISC" }, "node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, - "node_modules/hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hash-base/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "node_modules/hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "dev": true, - "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/htmlescape": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", - "integrity": "sha512-eVcrzgbR4tim7c7soKQKtxa/kQM4TzjnlU83rcZ9bHU6t31ehfV7SktN6McWgwPWg+JYMA/O3qpGxBvFq1z2Jg==", - "dev": true, - "engines": { - "node": ">=0.10" - } - }, "node_modules/http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", - "dev": true + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", + "dev": true, + "license": "BSD-2-Clause" }, "node_modules/http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", "dev": true, + "license": "MIT", "dependencies": { - "@tootallnate/once": "1", + "@tootallnate/once": "2", "agent-base": "6", "debug": "4" }, @@ -1647,32 +944,12 @@ "node": ">= 6" } }, - "node_modules/http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, - "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" - } - }, - "node_modules/https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==", - "dev": true - }, "node_modules/https-proxy-agent": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "dev": true, + "license": "MIT", "dependencies": { "agent-base": "6", "debug": "4" @@ -1686,6 +963,7 @@ "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", "dev": true, + "license": "MIT", "dependencies": { "ms": "^2.0.0" } @@ -1695,6 +973,7 @@ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" @@ -1703,37 +982,19 @@ "node": ">=0.10.0" } }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/iferr": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", "integrity": "sha512-DUNFN5j7Tln0D+TxzloUjKB+CtVu6myn0JEFak6dG18mNt9YkQ6lzGCdafwofISZ1lLF3xRHJ98VKy9ynkcFaA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.19" } @@ -1743,6 +1004,7 @@ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -1751,13 +1013,16 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, + "license": "ISC", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -1767,97 +1032,87 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "dev": true, + "license": "ISC" }, - "node_modules/inline-source-map": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz", - "integrity": "sha512-0mVWSSbNDvedDWIN4wxLsdPM4a7cIPcpyMxj3QZ406QRwQ6ePGB1YIHxVPjqpcUGbWQ5C+nHTwGNWAGvt7ggVA==", + "node_modules/ip-address": { + "version": "10.7.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.7.0.tgz", + "integrity": "sha512-BGFsyJd5mpXp3rK6jIdADLNgpJUK1jnjzvYF8lK+VyDab9JAmqN0YOKDdP17HlgKb2+ehPgDc8EtnRLbGCAMhA==", "dev": true, - "dependencies": { - "source-map": "~0.5.3" + "license": "MIT", + "engines": { + "node": ">= 12" } }, - "node_modules/insert-module-globals": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.2.1.tgz", - "integrity": "sha512-ufS5Qq9RZN+Bu899eA9QCAYThY+gGW7oRkmb0vC93Vlyu/CFGcH0OYPEjVkDXA5FEbTt1+VWzdoOD3Ny9N+8tg==", + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", "dev": true, - "dependencies": { - "acorn-node": "^1.5.2", - "combine-source-map": "^0.8.0", - "concat-stream": "^1.6.1", - "is-buffer": "^1.1.0", - "JSONStream": "^1.0.3", - "path-is-absolute": "^1.0.1", - "process": "~0.11.0", - "through2": "^2.0.0", - "undeclared-identifiers": "^1.1.2", - "xtend": "^4.0.0" - }, + "license": "MIT", "bin": { - "insert-module-globals": "bin/cmd.js" + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/insert-module-globals/node_modules/concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, - "engines": [ - "node >= 0.8" - ], - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" + "license": "MIT", + "engines": { + "node": ">=8" } }, - "node_modules/ip": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", - "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==", - "dev": true - }, - "node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "node_modules/is-core-module": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", - "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", "dev": true, + "license": "MIT", "dependencies": { - "has": "^1.0.3" + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true, "engines": { - "node": ">=4" + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-lambda": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } }, "node_modules/is-plain-obj": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -1867,6 +1122,7 @@ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -1874,139 +1130,91 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true + "node_modules/is-wsl": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.1.tgz", + "integrity": "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", - "dev": true - }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "dev": true - }, - "node_modules/json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/json-stable-stringify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz", - "integrity": "sha512-nKtD/Qxm7tWdZqJoldEC7fF0S41v0mWbeaXG3637stOWfyGxTgWTYE2wtfKmjzpvxv2MA2xzxsXOIiwUpkX6Qw==", "dev": true, - "dependencies": { - "jsonify": "~0.0.0" - } - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true - }, - "node_modules/jsonify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha512-trvBk1ki43VZptdBI5rIlG4YOzyeH/WefQt5rj1grasPn4iiZWKet8nkgc4GlsAylaztn0qZfUYOiTsASJFdNA==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/jsonparse": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", - "dev": true, - "engines": [ - "node >= 0.2.0" - ] + "license": "ISC" }, - "node_modules/JSONStream": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "node_modules/jackspeak": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.2.3.tgz", + "integrity": "sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==", "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - }, - "bin": { - "JSONStream": "bin.js" + "@isaacs/cliui": "^9.0.0" }, "engines": { - "node": "*" + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/jsprim": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", - "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "node_modules/jsonfile": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", + "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", "dev": true, + "license": "MIT", "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" + "universalify": "^2.0.0" }, - "engines": { - "node": ">=0.6.0" + "optionalDependencies": { + "graceful-fs": "^4.1.6" } }, - "node_modules/labeled-stream-splicer": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.2.tgz", - "integrity": "sha512-Ca4LSXFFZUjPScRaqOcFxneA0VpKZr4MMYCljyQr4LIewTLb3Y0IUTIsnBBsVubIeEfxeSZpSjSsRM8APEQaAw==", + "node_modules/linkify-it": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.2.tgz", + "integrity": "sha512-ONTm2jCMAVZjgQa/Fy1kScXsuOoF5NPTsoFBdE1KVIZ2vAh/r9+Bqo+0jINCBYnavTPQZz38QzFTme79ENoN3Q==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/markdown-it" + } + ], + "license": "MIT", "dependencies": { - "inherits": "^2.0.1", - "stream-splicer": "^2.0.0" + "uc.micro": "^2.0.0" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/lodash.memoize": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", - "integrity": "sha512-eDn9kqrAmVUC1wmZvlQ6Uhde44n+tXpqPrN8olQJbttgh0oKclk+SF54P47VEGE9CEiMeRwAP8BaM7UHvBkz2A==", - "dev": true - }, "node_modules/log-symbols": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^2.4.2" }, @@ -2015,17 +1223,19 @@ } }, "node_modules/log-update": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-3.4.0.tgz", - "integrity": "sha512-ILKe88NeMt4gmDvk/eb615U/IVn7K9KWGkoYbdatQ69Z65nj1ZzjM6fHXfcs0Uge+e+EGnMW7DY4T9yko8vWFg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", "dev": true, + "license": "MIT", "dependencies": { - "ansi-escapes": "^3.2.0", - "cli-cursor": "^2.1.0", - "wrap-ansi": "^5.0.0" + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" }, "engines": { - "node": ">=6" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -2036,64 +1246,77 @@ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, + "license": "ISC", "dependencies": { "yallist": "^3.0.2" } }, "node_modules/make-fetch-happen": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz", - "integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==", + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz", + "integrity": "sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==", "dev": true, + "license": "ISC", "dependencies": { - "agentkeepalive": "^4.1.3", - "cacache": "^15.2.0", + "agentkeepalive": "^4.2.1", + "cacache": "^16.1.0", "http-cache-semantics": "^4.1.0", - "http-proxy-agent": "^4.0.1", + "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.0", "is-lambda": "^1.0.1", - "lru-cache": "^6.0.0", - "minipass": "^3.1.3", + "lru-cache": "^7.7.1", + "minipass": "^3.1.6", "minipass-collect": "^1.0.2", - "minipass-fetch": "^1.3.2", + "minipass-fetch": "^2.0.3", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.2", + "negotiator": "^0.6.3", "promise-retry": "^2.0.1", - "socks-proxy-agent": "^6.0.0", - "ssri": "^8.0.0" + "socks-proxy-agent": "^7.0.0", + "ssri": "^9.0.0" }, "engines": { - "node": ">= 10" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/brace-expansion": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.4.tgz", + "integrity": "sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" } }, "node_modules/make-fetch-happen/node_modules/cacache": { - "version": "15.3.0", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz", - "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==", + "version": "16.1.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.1.3.tgz", + "integrity": "sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==", "dev": true, + "license": "ISC", "dependencies": { - "@npmcli/fs": "^1.0.0", - "@npmcli/move-file": "^1.0.1", + "@npmcli/fs": "^2.1.0", + "@npmcli/move-file": "^2.0.0", "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "glob": "^7.1.4", + "fs-minipass": "^2.1.0", + "glob": "^8.0.1", "infer-owner": "^1.0.4", - "lru-cache": "^6.0.0", - "minipass": "^3.1.1", + "lru-cache": "^7.7.1", + "minipass": "^3.1.6", "minipass-collect": "^1.0.2", "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.2", - "mkdirp": "^1.0.3", + "minipass-pipeline": "^1.2.4", + "mkdirp": "^1.0.4", "p-map": "^4.0.0", "promise-inflight": "^1.0.1", "rimraf": "^3.0.2", - "ssri": "^8.0.1", - "tar": "^6.0.2", - "unique-filename": "^1.1.1" + "ssri": "^9.0.0", + "tar": "^6.1.11", + "unique-filename": "^2.0.0" }, "engines": { - "node": ">= 10" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/make-fetch-happen/node_modules/chownr": { @@ -2101,29 +1324,50 @@ "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", "dev": true, + "license": "ISC", "engines": { "node": ">=10" } }, - "node_modules/make-fetch-happen/node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "node_modules/make-fetch-happen/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "dev": true, + "license": "ISC", "dependencies": { - "minipass": "^3.0.0" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" }, "engines": { - "node": ">= 8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/make-fetch-happen/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/make-fetch-happen/node_modules/minimatch": { + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz", + "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", "dev": true, + "license": "ISC", "dependencies": { - "yallist": "^4.0.0" + "brace-expansion": "^2.0.1" }, "engines": { "node": ">=10" @@ -2134,6 +1378,7 @@ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true, + "license": "MIT", "bin": { "mkdirp": "bin/cmd.js" }, @@ -2141,108 +1386,175 @@ "node": ">=10" } }, - "node_modules/make-fetch-happen/node_modules/ssri": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", - "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", + "node_modules/make-fetch-happen/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, + "license": "ISC", "dependencies": { - "minipass": "^3.1.1" + "glob": "^7.1.3" }, - "engines": { - "node": ">= 8" + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/make-fetch-happen/node_modules/tar": { - "version": "6.1.11", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", - "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", + "node_modules/make-fetch-happen/node_modules/rimraf/node_modules/brace-expansion": { + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", + "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", "dev": true, + "license": "MIT", "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/make-fetch-happen/node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" }, "engines": { - "node": ">= 10" + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/make-fetch-happen/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "node_modules/make-fetch-happen/node_modules/rimraf/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, + "license": "ISC", "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" } }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "node_modules/miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "node_modules/make-fetch-happen/node_modules/ssri": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz", + "integrity": "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==", "dev": true, + "license": "ISC", "dependencies": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" + "minipass": "^3.1.1" }, - "bin": { - "miller-rabin": "bin/miller-rabin" + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/miller-rabin/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "node_modules/make-fetch-happen/node_modules/unique-filename": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-2.0.1.tgz", + "integrity": "sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==", "dev": true, - "bin": { - "mime": "cli.js" + "license": "ISC", + "dependencies": { + "unique-slug": "^3.0.0" }, "engines": { - "node": ">=4" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "node_modules/make-fetch-happen/node_modules/unique-slug": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-3.0.0.tgz", + "integrity": "sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==", "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + }, "engines": { - "node": ">= 0.6" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/markdown-it": { + "version": "14.3.1", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.3.1.tgz", + "integrity": "sha512-4Ej49aYTDFIQ+uBkfX8GBvJGccoARxxPep+7aWTs55ozbjQJpW9M26Fe53vnGgvLeVzva/amzjQQaQu9w0vMhA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/markdown-it" + } + ], + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1", + "entities": "^4.5.0", + "linkify-it": "^5.0.2", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" + }, + "bin": { + "markdown-it": "bin/markdown-it.mjs" } }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "node_modules/mdurl": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.1.0.tgz", + "integrity": "sha512-1+HBaOx0zi/dQWht8rNv9MYf9qqpqL/kxI0hXImU6Y547zM6Sni8BQibt7ifgMcYtQg41ao3Ivd6cnSM86inpg==", + "dev": true, + "license": "MIT" + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, + "license": "MIT", "dependencies": { - "mime-db": "1.52.0" + "braces": "^3.0.3", + "picomatch": "^2.3.1" }, "engines": { - "node": ">= 0.6" + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/mimic-fn": { @@ -2250,27 +1562,17 @@ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", - "dev": true - }, "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -2279,16 +1581,21 @@ } }, "node_modules/minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/minipass": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.4.tgz", - "integrity": "sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw==", + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", "dev": true, + "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -2301,6 +1608,7 @@ "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", "dev": true, + "license": "ISC", "dependencies": { "minipass": "^3.0.0" }, @@ -2309,27 +1617,29 @@ } }, "node_modules/minipass-fetch": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz", - "integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.2.tgz", + "integrity": "sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==", "dev": true, + "license": "MIT", "dependencies": { - "minipass": "^3.1.0", + "minipass": "^3.1.6", "minipass-sized": "^1.0.3", - "minizlib": "^2.0.0" + "minizlib": "^2.1.2" }, "engines": { - "node": ">=8" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" }, "optionalDependencies": { - "encoding": "^0.1.12" + "encoding": "^0.1.13" } }, "node_modules/minipass-flush": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", - "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.7.tgz", + "integrity": "sha512-TbqTz9cUwWyHS2Dy89P3ocAGUGxKjjLuR9z8w4WUTGAVgEj17/4nhgo2Du56i0Fm3Pm30g4iA8Lcqctc76jCzA==", "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { "minipass": "^3.0.0" }, @@ -2342,6 +1652,7 @@ "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", "dev": true, + "license": "ISC", "dependencies": { "minipass": "^3.0.0" }, @@ -2354,6 +1665,7 @@ "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", "dev": true, + "license": "ISC", "dependencies": { "minipass": "^3.0.0" }, @@ -2365,13 +1677,15 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/minizlib": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", "dev": true, + "license": "MIT", "dependencies": { "minipass": "^3.0.0", "yallist": "^4.0.0" @@ -2384,13 +1698,15 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/mississippi": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "concat-stream": "^1.5.0", "duplexify": "^3.4.2", @@ -2407,26 +1723,12 @@ "node": ">=4.0.0" } }, - "node_modules/mississippi/node_modules/concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "engines": [ - "node >= 0.8" - ], - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", "dev": true, + "license": "MIT", "dependencies": { "minimist": "^1.2.6" }, @@ -2434,77 +1736,13 @@ "mkdirp": "bin/cmd.js" } }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "dev": true - }, - "node_modules/module-deps": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-6.2.3.tgz", - "integrity": "sha512-fg7OZaQBcL4/L+AK5f4iVqf9OMbCclXfy/znXRxTVhJSeW5AIlS9AwheYwDaXM3lVW7OBeaeUEY3gbaC6cLlSA==", - "dev": true, - "dependencies": { - "browser-resolve": "^2.0.0", - "cached-path-relative": "^1.0.2", - "concat-stream": "~1.6.0", - "defined": "^1.0.0", - "detective": "^5.2.0", - "duplexer2": "^0.1.2", - "inherits": "^2.0.1", - "JSONStream": "^1.0.3", - "parents": "^1.0.0", - "readable-stream": "^2.0.2", - "resolve": "^1.4.0", - "stream-combiner2": "^1.1.1", - "subarg": "^1.0.0", - "through2": "^2.0.0", - "xtend": "^4.0.0" - }, - "bin": { - "module-deps": "bin/cmd.js" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/module-deps/node_modules/concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "engines": [ - "node >= 0.8" - ], - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/mold-source-map": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/mold-source-map/-/mold-source-map-0.4.0.tgz", - "integrity": "sha512-Y0uA/sDKVuPgLd7BmaJOai+fqzjrOlR6vZgx5cJIvturI/xOPQPgbf3X7ZbzJd6MvqQ6ucIfK8dSteFyc2Mw2w==", - "dev": true, - "dependencies": { - "convert-source-map": "^1.1.0", - "through": "~2.2.7" - } - }, - "node_modules/mold-source-map/node_modules/through": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/through/-/through-2.2.7.tgz", - "integrity": "sha512-JIR0m0ybkmTcR8URann+HbwKmodP+OE8UCbsifQDYMLD5J3em1Cdn3MYPpbEd5elGDwmP98T+WbqP/tvzA5Mjg==", - "dev": true - }, "node_modules/move-concurrently": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", "integrity": "sha512-hdrFxZOycD/g6A6SoI2bB5NA/5NEqD0569+S47WZhPvm46sD50ZHdYaFmnua5lndde9rCHGjmfK7Z8BuCt/PcQ==", + "deprecated": "This package is no longer supported.", "dev": true, + "license": "ISC", "dependencies": { "aproba": "^1.1.1", "copy-concurrently": "^1.0.0", @@ -2514,61 +1752,37 @@ "run-queue": "^1.0.3" } }, - "node_modules/move-concurrently/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true + "dev": true, + "license": "MIT" }, - "node_modules/mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true + "node_modules/nan": { + "version": "2.28.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.28.0.tgz", + "integrity": "sha512-fTsDz99OTq2sVePhGdp4qQhggZFtKr64ZNVyVajRKtMOkJxYekplBh577PiJB12v/D3s2E5cGtOI45LWp6rnLQ==", + "dev": true, + "license": "MIT", + "optional": true }, "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } }, - "node_modules/node-static": { - "version": "0.7.11", - "resolved": "https://registry.npmjs.org/node-static/-/node-static-0.7.11.tgz", - "integrity": "sha512-zfWC/gICcqb74D9ndyvxZWaI1jzcoHmf4UTHWQchBNuNMxdBLJMDiUgZ1tjGLEIe/BMhj2DxKD8HOuc2062pDQ==", - "dev": true, - "dependencies": { - "colors": ">=0.6.0", - "mime": "^1.2.9", - "optimist": ">=0.3.4" - }, - "bin": { - "static": "bin/cli.js" - }, - "engines": { - "node": ">= 0.4.1" - } - }, "node_modules/npm-run-path": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-3.1.0.tgz", "integrity": "sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.0.0" }, @@ -2576,29 +1790,12 @@ "node": ">=8" } }, - "node_modules/oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, + "license": "ISC", "dependencies": { "wrappy": "1" } @@ -2608,6 +1805,7 @@ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, + "license": "MIT", "dependencies": { "mimic-fn": "^2.1.0" }, @@ -2618,42 +1816,31 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha512-snN4O4TkigujZphWLN0E//nQmm7790RYaE53DdL7ZYwee2D8DDo9/EyYiKUfN3rneWUjhJnueija3G9I2i0h3g==", + "node_modules/open": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz", + "integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==", "dev": true, + "license": "MIT", "dependencies": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - } - }, - "node_modules/optimist/node_modules/minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha512-iotkTvxc+TwOm5Ieim8VnSNvCDjCK9S8G3scJ50ZthspSxa7jx50jkhYduuAtAjvfDUwSgOwf8+If99AlOEhyw==", - "dev": true - }, - "node_modules/optimist/node_modules/wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha512-1tMA907+V4QmxV7dbRvb4/8MaRALK6q9Abid3ndMYnbyo8piisCmeONVqVSXqQA3KaP4SLt5b7ud6E2sqP8TFw==", - "dev": true, + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "wsl-utils": "^0.1.0" + }, "engines": { - "node": ">=0.4.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==", - "dev": true - }, "node_modules/p-finally": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz", "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -2663,6 +1850,7 @@ "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", "dev": true, + "license": "MIT", "dependencies": { "aggregate-error": "^3.0.0" }, @@ -2673,56 +1861,31 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" }, "node_modules/parallel-transform": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", "dev": true, + "license": "MIT", "dependencies": { "cyclist": "^1.0.1", "inherits": "^2.0.3", "readable-stream": "^2.1.5" } }, - "node_modules/parents": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", - "integrity": "sha512-mXKF3xkoUt5td2DoxpLmtOmZvko9VfFpwRwkKDHSNvgmpLAeBo18YDhcPbBzJq+QLCHMbGOfzia2cX4U+0v9Mg==", - "dev": true, - "dependencies": { - "path-platform": "~0.11.15" - } - }, - "node_modules/parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", - "dev": true, - "dependencies": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -2732,73 +1895,81 @@ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "node_modules/path-platform": { - "version": "0.11.15", - "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", - "integrity": "sha512-Y30dB6rab1A/nfEKsZxmr01nUotHX0c/ZiIAsCTatEe1CmS5Pm5He7fZ195bPT7RdquoaL8lLxFCMQi/bS7IJg==", + "node_modules/path-scurry": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, "engines": { - "node": ">= 0.8.0" + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "11.5.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.2.tgz", + "integrity": "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==", "dev": true, - "dependencies": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - }, + "license": "BlueOak-1.0.0", "engines": { - "node": ">=0.12" + "node": "20 || >=22" } }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", - "dev": true + "node_modules/path-scurry/node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "node_modules/picomatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", "dev": true, + "license": "MIT", "engines": { - "node": ">= 0.6.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/promise-inflight": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/promise-retry": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", "dev": true, + "license": "MIT", "dependencies": { "err-code": "^2.0.2", "retry": "^0.12.0" @@ -2807,65 +1978,12 @@ "node": ">=10" } }, - "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true - }, - "node_modules/public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "dependencies": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/public-encrypt/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/pulp": { - "version": "16.0.2", - "resolved": "https://registry.npmjs.org/pulp/-/pulp-16.0.2.tgz", - "integrity": "sha512-dvLRBMP2q1hgsHm9xRGskWJdx/Q3fDugLEAlT1zJIKRP7x/EWirMDi31jAWmM7oLkKC+3EedJ7i9d9NHeSb87A==", - "dev": true, - "dependencies": { - "browserify": "^16.2.3", - "browserify-incremental": "^3.1.1", - "concat-stream": "^2.0.0", - "gaze": "^1.1.3", - "glob": "^7.1.3", - "mold-source-map": "^0.4.0", - "node-static": "^0.7.11", - "read": "^1.0.7", - "sorcery": "^0.10.0", - "temp": "^0.9.0", - "through": "^2.3.8", - "tree-kill": "^1.2.1", - "which": "^1.3.1", - "wordwrap": "1.0.0" - }, - "bin": { - "pulp": "index.js" - }, - "engines": { - "node": ">= 4" - } - }, "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", + "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==", "dev": true, + "license": "MIT", "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -2876,6 +1994,7 @@ "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", "dev": true, + "license": "MIT", "dependencies": { "duplexify": "^3.6.0", "inherits": "^2.0.3", @@ -2887,37 +2006,53 @@ "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", "dev": true, + "license": "MIT", "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", - "dev": true + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } }, "node_modules/purescript": { - "version": "0.15.4", - "resolved": "https://registry.npmjs.org/purescript/-/purescript-0.15.4.tgz", - "integrity": "sha512-6Ge3IMcIxKkOUXg91cBgvjbqu5SxdfwbvWi1P4g+E2maxfvDv+roWAmLyOteTsxQE4SEa/wWoCZvnZ/AEjvrMw==", + "version": "0.15.16", + "resolved": "https://registry.npmjs.org/purescript/-/purescript-0.15.16.tgz", + "integrity": "sha512-3t936C7oUl/DT2n0U9SXO7TBG316EqywCUUuZ5naS9EhNc+Xpj+CUTjfNjlWffvN8oFDSWYdQGRFGJ73lXpCSQ==", "dev": true, "hasInstallScript": true, + "license": "ISC", "dependencies": { - "purescript-installer": "^0.2.6" + "purescript-installer": "^0.3.5" }, "bin": { "purs": "purs.bin" } }, "node_modules/purescript-installer": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/purescript-installer/-/purescript-installer-0.2.6.tgz", - "integrity": "sha512-22un7k/S0hETctsMMVlCEuXlvy1VAgN/uL49B65dQVPUVd17fh9CbB5kd9xoqiADUyw3t5HgL68lCwmDwrCCVw==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/purescript-installer/-/purescript-installer-0.3.5.tgz", + "integrity": "sha512-w04BBvW4BSQlspLsZ9Bs5vtUBZqvC4bC+FizC5GUp2/rpmYvXJ0CTf79Q3MKo2A8p1ZjqbhCI+SqdTQ30UZUIQ==", "dev": true, + "license": "ISC", "dependencies": { - "arch": "^2.1.1", "byline": "^5.0.0", "cacache": "^11.3.2", "chalk": "^2.4.2", @@ -2926,16 +2061,14 @@ "filesize": "^4.1.2", "is-plain-obj": "^2.0.0", "log-symbols": "^3.0.0", - "log-update": "^3.2.0", + "log-update": "^4.0.0", + "make-fetch-happen": "^10.0.0", "minimist": "^1.2.0", - "mkdirp": "^0.5.1", "ms": "^2.1.2", "once": "^1.4.0", - "pump": "^3.0.0", - "request": "^2.88.0", "rimraf": "^2.6.3", "semver": "^7.3.7", - "tar": "^4.4.6", + "tar": "^6.1.11", "which": "^1.3.1", "zen-observable": "^0.8.14" }, @@ -2943,321 +2076,172 @@ "install-purescript": "index.js" }, "engines": { - "node": ">=8.3.0" - } - }, - "node_modules/purescript-installer/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" + "node": ">=12" } }, - "node_modules/purescript-psa": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/purescript-psa/-/purescript-psa-0.8.2.tgz", - "integrity": "sha512-4Olf0aQQrNCfcDLXQI3gJgINEQ+3U+4QPLmQ2LHX2L/YOXSwM7fOGIUs/wMm/FQnwERUyQmHKQTJKB4LIjE2fg==", + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true, - "bin": { - "psa": "index.js" - } + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" }, - "node_modules/purs-tidy": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/purs-tidy/-/purs-tidy-0.9.0.tgz", - "integrity": "sha512-7la7Jw5CyuMDXJMliGiK746xevUScDCTJ0eMvN/mV/NAQF2c9Cqa31QNx5O15ae2d7SuFDqEiVALFzHYD601Cg==", + "node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, - "bin": { - "purs-tidy": "bin/index.js" + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, - "node_modules/qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "node_modules/readline-sync": { + "version": "1.4.10", + "resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.10.tgz", + "integrity": "sha512-gNva8/6UAe8QYepIQH/jQ2qn91Qj0B9sYjMBBs3QOB8F2CXcKgLxQaJRP76sWVRQt+QU+8fAkCbCvjjMFu7Ycw==", "dev": true, + "license": "MIT", "engines": { - "node": ">=0.6" + "node": ">= 0.8.0" } }, - "node_modules/querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", - "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, "engines": { - "node": ">=0.4.x" + "node": ">=8" } }, - "node_modules/querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==", + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", "dev": true, + "license": "MIT", "engines": { - "node": ">=0.4.x" + "node": ">= 4" } }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", "dev": true, - "dependencies": { - "safe-buffer": "^5.1.0" + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" } }, - "node_modules/randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, + "license": "ISC", "dependencies": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" } }, - "node_modules/read": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", - "integrity": "sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==", + "node_modules/run-applescript": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", + "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==", "dev": true, - "dependencies": { - "mute-stream": "~0.0.4" - }, + "license": "MIT", "engines": { - "node": ">=0.8" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/read-only-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz", - "integrity": "sha512-3ALe0bjBVZtkdWKIcThYpQCLbBMd/+Tbh2CDSrAIDO3UsZ4Xs+tnyjv2MjCOMMgBG+AsUOeuP1cgtY1INISc8w==", + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", "dependencies": { - "readable-stream": "^2.0.2" + "queue-microtask": "^1.2.2" } }, - "node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "node_modules/run-queue": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", + "integrity": "sha512-ntymy489o0/QQplUDnpYAYUsO50K9SBrIVaKCWDOJzYJts0f9WH9RFJkyagebkw5+y1oi00R7ynNW/d12GBumg==", "dev": true, + "license": "ISC", "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "aproba": "^1.1.1" } }, - "node_modules/readable-stream/node_modules/safe-buffer": { + "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/readable-stream/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", - "dev": true, - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", - "dev": true, - "dependencies": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==", - "dev": true, - "dependencies": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/restore-cursor/node_modules/mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/restore-cursor/node_modules/onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==", - "dev": true, - "dependencies": { - "mimic-fn": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "node_modules/run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha512-ntymy489o0/QQplUDnpYAYUsO50K9SBrIVaKCWDOJzYJts0f9WH9RFJkyagebkw5+y1oi00R7ynNW/d12GBumg==", - "dev": true, - "dependencies": { - "aproba": "^1.1.1" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] + "dev": true, + "license": "MIT" }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "node_modules/sander": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/sander/-/sander-0.5.1.tgz", - "integrity": "sha512-3lVqBir7WuKDHGrKRDn/1Ye3kwpXaDOMsiRP1wd6wpZW56gJhsbp5RqQpA6JG/P+pkXizygnr1dKR8vzWaVsfA==", - "dev": true, - "dependencies": { - "es6-promise": "^3.1.2", - "graceful-fs": "^4.1.3", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.2" - } - }, - "node_modules/sander/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } + "license": "MIT" }, "node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -3265,61 +2249,12 @@ "node": ">=10" } }, - "node_modules/semver/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - }, - "bin": { - "sha.js": "bin.js" - } - }, - "node_modules/shasum": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/shasum/-/shasum-1.0.2.tgz", - "integrity": "sha512-UTzHm/+AzKfO9RgPgRpDIuMSNie1ubXRaljjlhFMNGYoG7z+rm9AHLPMf70R7887xboDH9Q+5YQbWKObFHEAtw==", - "dev": true, - "dependencies": { - "json-stable-stringify": "~0.0.0", - "sha.js": "~2.4.4" - } - }, - "node_modules/shasum-object": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shasum-object/-/shasum-object-1.0.0.tgz", - "integrity": "sha512-Iqo5rp/3xVi6M4YheapzZhhGPVs0yZwHj7wvwQ1B9z8H6zk+FEnI7y3Teq7qwnekfEhu8WmG2z0z4iWZaxLWVg==", - "dev": true, - "dependencies": { - "fast-safe-stringify": "^2.0.7" - } - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, + "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -3332,71 +2267,104 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/shell-quote": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.3.tgz", - "integrity": "sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==", - "dev": true - }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true + "dev": true, + "license": "ISC" }, - "node_modules/simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/slice-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" }, "node_modules/smart-buffer": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 6.0.0", "npm": ">= 3.0.0" } }, "node_modules/socks": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.0.tgz", - "integrity": "sha512-scnOe9y4VuiNUULJN72GrM26BNOjVsfPXI+j+98PkyEfsIXroa5ofyjT+FzGvn/xHs73U2JtoBYAVx9Hl4quSA==", + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.9.tgz", + "integrity": "sha512-LJhUYUvItdQ0LkJTmPeaEObWXAqFyfmP85x0tch/ez9cahmhlBBLbIqDFnvBnUJGagb0JbIQrkBs1wJ+yRYpEw==", "dev": true, + "license": "MIT", "dependencies": { - "ip": "^2.0.0", + "ip-address": "^10.1.1", "smart-buffer": "^4.2.0" }, "engines": { - "node": ">= 10.13.0", + "node": ">= 10.0.0", "npm": ">= 3.0.0" } }, "node_modules/socks-proxy-agent": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz", - "integrity": "sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", + "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", "dev": true, + "license": "MIT", "dependencies": { "agent-base": "^6.0.2", "debug": "^4.3.3", @@ -3406,4051 +2374,629 @@ "node": ">= 10" } }, - "node_modules/sorcery": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/sorcery/-/sorcery-0.10.0.tgz", - "integrity": "sha512-R5ocFmKZQFfSTstfOtHjJuAwbpGyf9qjQa1egyhvXSbM7emjrtLXtGdZsDJDABC85YBfVvrOiGWKSYXPKdvP1g==", - "dev": true, - "dependencies": { - "buffer-crc32": "^0.2.5", - "minimist": "^1.2.0", - "sander": "^0.5.0", - "sourcemap-codec": "^1.3.0" + "node_modules/spago": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/spago/-/spago-1.0.4.tgz", + "integrity": "sha512-iv1HBJppzGJRWWd/DZ32oselcKrhq/PboBdXy5VMX4GiwRqLCUUp3loZ6Yhm8zymNRKHkN/w52cxX6k521nwng==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@nodelib/fs.walk": "^3.0.1", + "env-paths": "^3.0.0", + "fs-extra": "^11.3.0", + "fuse.js": "^7.1.0", + "glob": "^11.0.1", + "markdown-it": "^14.1.0", + "micromatch": "^4.0.8", + "open": "^10.1.0", + "picomatch": "^4.0.2", + "punycode": "^2.3.1", + "readline-sync": "^1.4.10", + "semver": "^7.7.1", + "spdx-expression-parse": "^4.0.0", + "ssh2": "^1.16.0", + "supports-color": "^10.0.0", + "tar": "^7.4.3", + "tmp": "^0.2.3", + "xhr2": "^0.2.1", + "yaml": "^2.7.0" }, "bin": { - "sorcery": "bin/index.js" + "spago": "bin/bundle.js" + }, + "engines": { + "node": ">=22.5.0" } }, - "node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "node_modules/spago/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "dev": true, + "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": "18 || 20 || >=22" } }, - "node_modules/sourcemap-codec": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", - "dev": true - }, - "node_modules/spago": { - "version": "0.20.9", - "resolved": "https://registry.npmjs.org/spago/-/spago-0.20.9.tgz", - "integrity": "sha512-r5TUxnYn9HawlQyMswlhIk24BGFSN2KGbqgZFZrn47GjTpMscU14xkt9CqTWgoSQYsoZieG+3dUtOxUQ7GYD7w==", + "node_modules/spago/node_modules/brace-expansion": { + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz", + "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==", "dev": true, - "hasInstallScript": true, + "license": "MIT", "dependencies": { - "make-fetch-happen": "^9.1.0", - "tar": "^6.1.11" + "balanced-match": "^4.0.2" }, - "bin": { - "spago": "spago" + "engines": { + "node": "20 || >=22" } }, "node_modules/spago/node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", "dev": true, + "license": "BlueOak-1.0.0", "engines": { - "node": ">=10" + "node": ">=18" } }, - "node_modules/spago/node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "node_modules/spago/node_modules/env-paths": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-3.0.0.tgz", + "integrity": "sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==", "dev": true, - "dependencies": { - "minipass": "^3.0.0" - }, + "license": "MIT", "engines": { - "node": ">= 8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/spago/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "node_modules/spago/node_modules/glob": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz", + "integrity": "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "foreground-child": "^3.3.1", + "jackspeak": "^4.1.1", + "minimatch": "^10.1.1", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" + }, "bin": { - "mkdirp": "bin/cmd.js" + "glob": "dist/esm/bin.mjs" }, "engines": { - "node": ">=10" + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/spago/node_modules/tar": { - "version": "6.1.11", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", - "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", + "node_modules/spago/node_modules/minimatch": { + "version": "10.2.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz", + "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==", "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" + "brace-expansion": "^5.0.8" }, "engines": { - "node": ">= 10" + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/spago/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "node_modules/spago/node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } }, - "node_modules/sshpk": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", - "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", + "node_modules/spago/node_modules/minizlib": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", + "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", "dev": true, + "license": "MIT", "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" + "minipass": "^7.1.2" }, "engines": { - "node": ">=0.10.0" + "node": ">= 18" } }, - "node_modules/ssri": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz", - "integrity": "sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==", - "dev": true, - "dependencies": { - "figgy-pudding": "^3.5.1" - } - }, - "node_modules/stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "dependencies": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - } - }, - "node_modules/stream-combiner2": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", - "integrity": "sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw==", - "dev": true, - "dependencies": { - "duplexer2": "~0.1.0", - "readable-stream": "^2.0.2" - } - }, - "node_modules/stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "node_modules/stream-http": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz", - "integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==", - "dev": true, - "dependencies": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "xtend": "^4.0.2" - } - }, - "node_modules/stream-http/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "node_modules/stream-splicer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.1.tgz", - "integrity": "sha512-Xizh4/NPuYSyAXyT7g8IvdJ9HJpxIGL9PjyhtywCZvvP0OPIdqyrr4dMikeuvY8xahpdKEBlBTySe583totajg==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.2" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/subarg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", - "integrity": "sha512-RIrIdRY0X1xojthNcVtgT9sjpOGagEUKpZdgBUi054OEPFo282yg+zE+t1Rj3+RqKq2xStL7uUHhY+AjbC4BXg==", - "dev": true, - "dependencies": { - "minimist": "^1.1.0" - } - }, - "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "node_modules/spago/node_modules/supports-color": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz", + "integrity": "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==", "dev": true, + "license": "MIT", "engines": { - "node": ">= 0.4" + "node": ">=18" }, "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/syntax-error": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.4.0.tgz", - "integrity": "sha512-YPPlu67mdnHGTup2A8ff7BC2Pjq0e0Yp/IyTFN03zWO0RcK07uLcbi7C2KpGR2FvWbaB0+bfE27a+sBKebSo7w==", - "dev": true, - "dependencies": { - "acorn-node": "^1.2.0" - } - }, - "node_modules/tar": { - "version": "4.4.19", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", - "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", - "dev": true, - "dependencies": { - "chownr": "^1.1.4", - "fs-minipass": "^1.2.7", - "minipass": "^2.9.0", - "minizlib": "^1.3.3", - "mkdirp": "^0.5.5", - "safe-buffer": "^5.2.1", - "yallist": "^3.1.1" - }, - "engines": { - "node": ">=4.5" - } - }, - "node_modules/tar/node_modules/minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "node_modules/tar/node_modules/minizlib": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", - "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", - "dev": true, - "dependencies": { - "minipass": "^2.9.0" - } - }, - "node_modules/temp": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/temp/-/temp-0.9.4.tgz", - "integrity": "sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA==", - "dev": true, - "dependencies": { - "mkdirp": "^0.5.1", - "rimraf": "~2.6.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/temp/node_modules/rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true - }, - "node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/timers-browserify": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz", - "integrity": "sha512-PIxwAupJZiYU4JmVZYwXp9FKsHMXb5h0ZEFyuXTAn8WLHOlcij+FEcbrvDsom1o5dr1YggEtFbECvGCW2sT53Q==", - "dev": true, - "dependencies": { - "process": "~0.11.0" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/tough-cookie/node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/tree-kill": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", - "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", - "dev": true, - "bin": { - "tree-kill": "cli.js" - } - }, - "node_modules/tty-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", - "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", - "dev": true - }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true - }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true - }, - "node_modules/umd": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.3.tgz", - "integrity": "sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow==", - "dev": true, - "bin": { - "umd": "bin/cli.js" + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/undeclared-identifiers": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/undeclared-identifiers/-/undeclared-identifiers-1.1.3.tgz", - "integrity": "sha512-pJOW4nxjlmfwKApE4zvxLScM/njmwj/DiUBv7EabwE4O8kRUy+HIwxQtZLBPll/jx1LJyBcqNfB3/cpv9EZwOw==", + "node_modules/spago/node_modules/tar": { + "version": "7.5.22", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.22.tgz", + "integrity": "sha512-MFO/QzvtAOmJbkhOaCTvbGcFN9L9b+JunIsDwaKljSOdcLMea3NJ1k9Usz/rjdfSXTq4dfzfeS7W4p4YOAAHeA==", "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "acorn-node": "^1.3.0", - "dash-ast": "^1.0.0", - "get-assigned-identifiers": "^1.2.0", - "simple-concat": "^1.0.0", - "xtend": "^4.0.1" + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.1.0", + "yallist": "^5.0.0" }, - "bin": { - "undeclared-identifiers": "bin.js" - } - }, - "node_modules/unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dev": true, - "dependencies": { - "unique-slug": "^2.0.0" - } - }, - "node_modules/unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/uri-js/node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true, "engines": { - "node": ">=6" + "node": ">=18" } }, - "node_modules/url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==", - "dev": true, - "dependencies": { - "punycode": "1.3.2", - "querystring": "0.2.0" - } - }, - "node_modules/url/node_modules/punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==", - "dev": true - }, - "node_modules/util": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", - "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", - "dev": true, - "dependencies": { - "inherits": "2.0.3" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true - }, - "node_modules/util/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", - "dev": true - }, - "node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "dev": true, - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "node_modules/verror/node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "dev": true - }, - "node_modules/vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, - "node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "dev": true - }, - "node_modules/wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "engines": { - "node": ">=0.4" - } - }, - "node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "node_modules/zen-observable": { - "version": "0.8.15", - "resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.15.tgz", - "integrity": "sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==", - "dev": true - } - }, - "dependencies": { - "@gar/promisify": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", - "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", - "dev": true - }, - "@npmcli/fs": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz", - "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==", - "dev": true, - "requires": { - "@gar/promisify": "^1.0.1", - "semver": "^7.3.5" - } - }, - "@npmcli/move-file": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", - "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", - "dev": true, - "requires": { - "mkdirp": "^1.0.4", - "rimraf": "^3.0.2" - }, - "dependencies": { - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - } - } - }, - "@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "dev": true - }, - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true - }, - "acorn-node": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz", - "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==", - "dev": true, - "requires": { - "acorn": "^7.0.0", - "acorn-walk": "^7.0.0", - "xtend": "^4.0.2" - } - }, - "acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", - "dev": true - }, - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "requires": { - "debug": "4" - } - }, - "agentkeepalive": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.2.1.tgz", - "integrity": "sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "depd": "^1.1.2", - "humanize-ms": "^1.2.1" - } - }, - "aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", - "dev": true - }, - "ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "arch": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", - "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", - "dev": true - }, - "asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dev": true, - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "assert": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", - "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", - "dev": true, - "requires": { - "object-assign": "^4.1.1", - "util": "0.10.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA==", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha512-5KiHfsmkqacuKjkRkdV7SsfDJ2EGiPsK92s2MhNSY0craxjTdKTtqKsJaCWp4LW33ZZ0OPUv1WO/TFvNQRiQxQ==", - "dev": true, - "requires": { - "inherits": "2.0.1" - } - } - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true - }, - "async": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", - "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", - "dev": true - }, - "aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", - "dev": true - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", - "dev": true, - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, - "bower": { - "version": "1.8.14", - "resolved": "https://registry.npmjs.org/bower/-/bower-1.8.14.tgz", - "integrity": "sha512-8Rq058FD91q9Nwthyhw0la9fzpBz0iwZTrt51LWl+w+PnJgZk9J+5wp3nibsJcIUPglMYXr4NRBaR+TUj0OkBQ==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", - "dev": true - }, - "browser-pack": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.1.0.tgz", - "integrity": "sha512-erYug8XoqzU3IfcU8fUgyHqyOXqIE4tUTTQ+7mqUjQlvnXkOO6OlT9c/ZoJVHYoAaqGxr09CN53G7XIsO4KtWA==", - "dev": true, - "requires": { - "combine-source-map": "~0.8.0", - "defined": "^1.0.0", - "JSONStream": "^1.0.3", - "safe-buffer": "^5.1.1", - "through2": "^2.0.0", - "umd": "^3.0.0" - } - }, - "browser-resolve": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-2.0.0.tgz", - "integrity": "sha512-7sWsQlYL2rGLy2IWm8WL8DCTJvYLc/qlOnsakDac87SOoCd16WLsaAMdCiAqsTNHIe+SXfaqyxyo6THoWqs8WQ==", - "dev": true, - "requires": { - "resolve": "^1.17.0" - } - }, - "browserify": { - "version": "16.5.2", - "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.5.2.tgz", - "integrity": "sha512-TkOR1cQGdmXU9zW4YukWzWVSJwrxmNdADFbqbE3HFgQWe5wqZmOawqZ7J/8MPCwk/W8yY7Y0h+7mOtcZxLP23g==", - "dev": true, - "requires": { - "assert": "^1.4.0", - "browser-pack": "^6.0.1", - "browser-resolve": "^2.0.0", - "browserify-zlib": "~0.2.0", - "buffer": "~5.2.1", - "cached-path-relative": "^1.0.0", - "concat-stream": "^1.6.0", - "console-browserify": "^1.1.0", - "constants-browserify": "~1.0.0", - "crypto-browserify": "^3.0.0", - "defined": "^1.0.0", - "deps-sort": "^2.0.0", - "domain-browser": "^1.2.0", - "duplexer2": "~0.1.2", - "events": "^2.0.0", - "glob": "^7.1.0", - "has": "^1.0.0", - "htmlescape": "^1.1.0", - "https-browserify": "^1.0.0", - "inherits": "~2.0.1", - "insert-module-globals": "^7.0.0", - "JSONStream": "^1.0.3", - "labeled-stream-splicer": "^2.0.0", - "mkdirp-classic": "^0.5.2", - "module-deps": "^6.2.3", - "os-browserify": "~0.3.0", - "parents": "^1.0.1", - "path-browserify": "~0.0.0", - "process": "~0.11.0", - "punycode": "^1.3.2", - "querystring-es3": "~0.2.0", - "read-only-stream": "^2.0.0", - "readable-stream": "^2.0.2", - "resolve": "^1.1.4", - "shasum": "^1.0.0", - "shell-quote": "^1.6.1", - "stream-browserify": "^2.0.0", - "stream-http": "^3.0.0", - "string_decoder": "^1.1.1", - "subarg": "^1.0.0", - "syntax-error": "^1.1.1", - "through2": "^2.0.0", - "timers-browserify": "^1.0.1", - "tty-browserify": "0.0.1", - "url": "~0.11.0", - "util": "~0.10.1", - "vm-browserify": "^1.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - } - } - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cache-api": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/browserify-cache-api/-/browserify-cache-api-3.0.2.tgz", - "integrity": "sha512-14YNbboSgSHY5QNZSLwlGYB7OuBuXS7gMyR2gfBjdS4JYcWB9BqyKhraQG/VW2W5ZhjkC/C8LZ38sP3bmbmeNA==", - "dev": true, - "requires": { - "async": "^2.6.4", - "through2": "^2.0.0", - "xtend": "^4.0.0" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-incremental": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/browserify-incremental/-/browserify-incremental-3.1.1.tgz", - "integrity": "sha512-PrFwOzLEdy27VRXK2uGjmjLq1aROBG7QoQq3eKanmm6Q8vuzT0ZNFCORHh3yJgNQQooXA9tOizGv4vCOmhrvRQ==", - "dev": true, - "requires": { - "browserify-cache-api": "^3.0.0", - "JSONStream": "^0.10.0", - "through2": "^2.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "jsonparse": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-0.0.5.tgz", - "integrity": "sha512-fw7Q/8gFR8iSekUi9I+HqWIap6mywuoe7hQIg3buTVjuZgALKj4HAmm0X6f+TaL4c9NJbvyFQdaI2ppr5p6dnQ==", - "dev": true - }, - "JSONStream": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-0.10.0.tgz", - "integrity": "sha512-8XbSFFd43EG+1thjLNFIzCBlwXti0yKa7L+ak/f0T/pkC+31b7G41DXL/JzYpAoYWZ2eCPiu4IIqzijM8N0a/w==", - "dev": true, - "requires": { - "jsonparse": "0.0.5", - "through": ">=2.2.7 <3" - } - } - } - }, - "browserify-rsa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", - "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", - "dev": true, - "requires": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - } - }, - "browserify-sign": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", - "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", - "dev": true, - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.3", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - } - }, - "buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", - "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "dev": true - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==", - "dev": true - }, - "byline": { + "node_modules/spago/node_modules/yallist": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/byline/-/byline-5.0.0.tgz", - "integrity": "sha512-s6webAy+R4SR8XVuJWt2V2rGvhnrhxN+9S15GNuTK3wKPOXFF6RNc+8ug2XhH+2s4f+uudG4kUVYmYOQWL2g0Q==", - "dev": true - }, - "cacache": { - "version": "11.3.3", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.3.tgz", - "integrity": "sha512-p8WcneCytvzPxhDvYp31PD039vi77I12W+/KfR9S8AZbaiARFBCpsPJS+9uhWfeBfeAtW7o/4vt3MUqLkbY6nA==", - "dev": true, - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - }, - "dependencies": { - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } - } - }, - "cached-path-relative": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.1.0.tgz", - "integrity": "sha512-WF0LihfemtesFcJgO7xfOoOcnWzY/QHR4qeDqV44jPU3HTI54+LnfXK3SA27AVVGCdZFgjjFFaqUA9Jx7dMJZA==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", - "dev": true - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==", - "dev": true, - "requires": { - "restore-cursor": "^2.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true - }, - "combine-source-map": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", - "integrity": "sha512-UlxQ9Vw0b/Bt/KYwCFqdEwsQ1eL8d1gibiFb7lxQJFdvTgc2hIZi6ugsg+kyhzhPV+QEpUiEIwInIAIrgoEkrg==", - "dev": true, - "requires": { - "convert-source-map": "~1.1.0", - "inline-source-map": "~0.6.0", - "lodash.memoize": "~3.0.3", - "source-map": "~0.5.3" - } - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "concat-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", - "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.0.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==", - "dev": true - }, - "convert-source-map": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", - "integrity": "sha512-Y8L5rp6jo+g9VEPgvqNfEopjTR4OTYct8lXlS8iVQdmnjDvbdbzYe9rjtFCB9egC86JoNCU61WRY+ScjkZpnIg==", - "dev": true - }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - }, - "dependencies": { - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } - } - }, - "core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true - }, - "create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "dependencies": { - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha512-NJGVKPS81XejHcLhaLJS7plab0fK3slPh11mESeeDq2W4ZI5kUKK/LRRdVDvjJseojbPB7ZwjnyOybg3Igea/A==", - "dev": true - }, - "dash-ast": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/dash-ast/-/dash-ast-1.0.0.tgz", - "integrity": "sha512-Vy4dx7gquTeMcQR/hDkYLGUnwVil6vk4FOOct+djUnHOUWt+zJPJAaRIXaAFkPXtJjvlY7o3rfRu0/3hpnwoUA==", - "dev": true - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - }, - "dependencies": { - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "defined": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", - "integrity": "sha512-Y2caI5+ZwS5c3RiNDJ6u53VhQHv+hHKwhkI1iHvceKUHw9Df6EK2zRLfjejRgMuCuxK7PfSWIMwWecceVvThjQ==", - "dev": true - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", - "dev": true - }, - "deps-sort": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.1.tgz", - "integrity": "sha512-1orqXQr5po+3KI6kQb9A4jnXT1PBwggGl2d7Sq2xsnOeI9GPcE/tGcF9UiSZtZBM7MukY4cAh7MemS6tZYipfw==", - "dev": true, - "requires": { - "JSONStream": "^1.0.3", - "shasum-object": "^1.0.0", - "subarg": "^1.0.0", - "through2": "^2.0.0" - } - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "detective": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.1.tgz", - "integrity": "sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==", - "dev": true, - "requires": { - "acorn-node": "^1.8.2", - "defined": "^1.0.0", - "minimist": "^1.2.6" - } - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", - "dev": true, - "requires": { - "readable-stream": "^2.0.2" - } - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", - "dev": true, - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "encoding": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", - "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", - "dev": true, - "optional": true, - "requires": { - "iconv-lite": "^0.6.2" - } - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "dev": true - }, - "err-code": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", - "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", - "dev": true - }, - "es6-promise": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", - "integrity": "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "events": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-2.1.0.tgz", - "integrity": "sha512-3Zmiobend8P9DjmKAty0Era4jV8oJ0yGYe2nJJAxgymF9+N8F2m0hhZiMoWtcfepExzNKZumFU3ksdQbInGWCg==", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "execa": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-2.1.0.tgz", - "integrity": "sha512-Y/URAVapfbYy2Xp/gb6A0E7iR8xeqOCXsuuaoMn7A5PzrXUK84E1gyiEfq0wQd/GHA6GsoHWwhNq8anb0mleIw==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^3.0.0", - "onetime": "^5.1.0", - "p-finally": "^2.0.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", - "dev": true - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fast-safe-stringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", - "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", - "dev": true - }, - "figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", - "dev": true - }, - "filesize": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/filesize/-/filesize-4.2.1.tgz", - "integrity": "sha512-bP82Hi8VRZX/TUBKfE24iiUGsB/sfm2WUrwTQyAzQrhO3V9IhcBBNBXMyzLY5orACxRyYJ3d2HeRVX+eFv4lmA==", - "dev": true - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", - "dev": true - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - } - }, - "fs-minipass": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", - "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", - "dev": true, - "requires": { - "minipass": "^2.6.0" - }, - "dependencies": { - "minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - } - } - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha512-gehEzmPn2nAwr39eay+x3X34Ra+M2QlVUTLhkXPjWdeO8RF9kszk116avgBJM3ZyNHgHXBNx+VmPaFC36k0PzA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "gaze": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", - "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", - "dev": true, - "requires": { - "globule": "^1.0.0" - } - }, - "get-assigned-identifiers": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz", - "integrity": "sha512-mBBwmeGTrxEMO4pMaaf/uUEFHnYtwr8FTe8Y/mer4rcV/bye0qGm6pw1bGZFGStxC5O76c5ZAVBGnqHmOaJpdQ==", - "dev": true - }, - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "globule": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.4.tgz", - "integrity": "sha512-OPTIfhMBh7JbBYDpa5b+Q5ptmMWKwcNcFSR/0c6t8V4f3ZAVBEsKNY37QdVqmLRYSMhOUGYrY0QhSoEpzGr/Eg==", - "dev": true, - "requires": { - "glob": "~7.1.1", - "lodash": "^4.17.21", - "minimatch": "~3.0.2" - }, - "dependencies": { - "glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "minimatch": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", - "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } - } - }, - "graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "dev": true - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", - "dev": true - }, - "har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "dev": true, - "requires": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "htmlescape": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", - "integrity": "sha512-eVcrzgbR4tim7c7soKQKtxa/kQM4TzjnlU83rcZ9bHU6t31ehfV7SktN6McWgwPWg+JYMA/O3qpGxBvFq1z2Jg==", - "dev": true - }, - "http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", - "dev": true - }, - "http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "dev": true, - "requires": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==", - "dev": true - }, - "https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dev": true, - "requires": { - "agent-base": "6", - "debug": "4" - } - }, - "humanize-ms": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", - "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", - "dev": true, - "requires": { - "ms": "^2.0.0" - } - }, - "iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true - }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha512-DUNFN5j7Tln0D+TxzloUjKB+CtVu6myn0JEFak6dG18mNt9YkQ6lzGCdafwofISZ1lLF3xRHJ98VKy9ynkcFaA==", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true - }, - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "inline-source-map": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz", - "integrity": "sha512-0mVWSSbNDvedDWIN4wxLsdPM4a7cIPcpyMxj3QZ406QRwQ6ePGB1YIHxVPjqpcUGbWQ5C+nHTwGNWAGvt7ggVA==", - "dev": true, - "requires": { - "source-map": "~0.5.3" - } - }, - "insert-module-globals": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.2.1.tgz", - "integrity": "sha512-ufS5Qq9RZN+Bu899eA9QCAYThY+gGW7oRkmb0vC93Vlyu/CFGcH0OYPEjVkDXA5FEbTt1+VWzdoOD3Ny9N+8tg==", - "dev": true, - "requires": { - "acorn-node": "^1.5.2", - "combine-source-map": "^0.8.0", - "concat-stream": "^1.6.1", - "is-buffer": "^1.1.0", - "JSONStream": "^1.0.3", - "path-is-absolute": "^1.0.1", - "process": "~0.11.0", - "through2": "^2.0.0", - "undeclared-identifiers": "^1.1.2", - "xtend": "^4.0.0" - }, - "dependencies": { - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - } - } - }, - "ip": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", - "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==", - "dev": true - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "is-core-module": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", - "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true - }, - "is-lambda": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", - "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", - "dev": true - }, - "is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true - }, - "is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", - "dev": true - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "dev": true - }, - "json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stable-stringify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz", - "integrity": "sha512-nKtD/Qxm7tWdZqJoldEC7fF0S41v0mWbeaXG3637stOWfyGxTgWTYE2wtfKmjzpvxv2MA2xzxsXOIiwUpkX6Qw==", - "dev": true, - "requires": { - "jsonify": "~0.0.0" - } - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true - }, - "jsonify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha512-trvBk1ki43VZptdBI5rIlG4YOzyeH/WefQt5rj1grasPn4iiZWKet8nkgc4GlsAylaztn0qZfUYOiTsASJFdNA==", - "dev": true - }, - "jsonparse": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", - "dev": true - }, - "JSONStream": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", - "dev": true, - "requires": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - } - }, - "jsprim": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", - "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - } - }, - "labeled-stream-splicer": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.2.tgz", - "integrity": "sha512-Ca4LSXFFZUjPScRaqOcFxneA0VpKZr4MMYCljyQr4LIewTLb3Y0IUTIsnBBsVubIeEfxeSZpSjSsRM8APEQaAw==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "stream-splicer": "^2.0.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "lodash.memoize": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", - "integrity": "sha512-eDn9kqrAmVUC1wmZvlQ6Uhde44n+tXpqPrN8olQJbttgh0oKclk+SF54P47VEGE9CEiMeRwAP8BaM7UHvBkz2A==", - "dev": true - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2" - } - }, - "log-update": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-3.4.0.tgz", - "integrity": "sha512-ILKe88NeMt4gmDvk/eb615U/IVn7K9KWGkoYbdatQ69Z65nj1ZzjM6fHXfcs0Uge+e+EGnMW7DY4T9yko8vWFg==", - "dev": true, - "requires": { - "ansi-escapes": "^3.2.0", - "cli-cursor": "^2.1.0", - "wrap-ansi": "^5.0.0" - } - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "make-fetch-happen": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz", - "integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==", - "dev": true, - "requires": { - "agentkeepalive": "^4.1.3", - "cacache": "^15.2.0", - "http-cache-semantics": "^4.1.0", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-lambda": "^1.0.1", - "lru-cache": "^6.0.0", - "minipass": "^3.1.3", - "minipass-collect": "^1.0.2", - "minipass-fetch": "^1.3.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.2", - "promise-retry": "^2.0.1", - "socks-proxy-agent": "^6.0.0", - "ssri": "^8.0.0" - }, - "dependencies": { - "cacache": { - "version": "15.3.0", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz", - "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==", - "dev": true, - "requires": { - "@npmcli/fs": "^1.0.0", - "@npmcli/move-file": "^1.0.1", - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "glob": "^7.1.4", - "infer-owner": "^1.0.4", - "lru-cache": "^6.0.0", - "minipass": "^3.1.1", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.2", - "mkdirp": "^1.0.3", - "p-map": "^4.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^3.0.2", - "ssri": "^8.0.1", - "tar": "^6.0.2", - "unique-filename": "^1.1.1" - } - }, - "chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true - }, - "fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - }, - "ssri": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", - "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", - "dev": true, - "requires": { - "minipass": "^3.1.1" - } - }, - "tar": { - "version": "6.1.11", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", - "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", - "dev": true, - "requires": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true - }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true - }, - "mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "requires": { - "mime-db": "1.52.0" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", - "dev": true - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true - }, - "minipass": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.4.tgz", - "integrity": "sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - }, - "dependencies": { - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } - }, - "minipass-collect": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", - "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "minipass-fetch": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz", - "integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==", - "dev": true, - "requires": { - "encoding": "^0.1.12", - "minipass": "^3.1.0", - "minipass-sized": "^1.0.3", - "minizlib": "^2.0.0" - } - }, - "minipass-flush": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", - "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "minipass-pipeline": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", - "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "minipass-sized": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", - "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dev": true, - "requires": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "dependencies": { - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } - }, - "mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "dev": true, - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - }, - "dependencies": { - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - } - } - }, - "mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "requires": { - "minimist": "^1.2.6" - } - }, - "mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "dev": true - }, - "module-deps": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-6.2.3.tgz", - "integrity": "sha512-fg7OZaQBcL4/L+AK5f4iVqf9OMbCclXfy/znXRxTVhJSeW5AIlS9AwheYwDaXM3lVW7OBeaeUEY3gbaC6cLlSA==", - "dev": true, - "requires": { - "browser-resolve": "^2.0.0", - "cached-path-relative": "^1.0.2", - "concat-stream": "~1.6.0", - "defined": "^1.0.0", - "detective": "^5.2.0", - "duplexer2": "^0.1.2", - "inherits": "^2.0.1", - "JSONStream": "^1.0.3", - "parents": "^1.0.0", - "readable-stream": "^2.0.2", - "resolve": "^1.4.0", - "stream-combiner2": "^1.1.1", - "subarg": "^1.0.0", - "through2": "^2.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - } - } - }, - "mold-source-map": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/mold-source-map/-/mold-source-map-0.4.0.tgz", - "integrity": "sha512-Y0uA/sDKVuPgLd7BmaJOai+fqzjrOlR6vZgx5cJIvturI/xOPQPgbf3X7ZbzJd6MvqQ6ucIfK8dSteFyc2Mw2w==", - "dev": true, - "requires": { - "convert-source-map": "^1.1.0", - "through": "~2.2.7" - }, - "dependencies": { - "through": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/through/-/through-2.2.7.tgz", - "integrity": "sha512-JIR0m0ybkmTcR8URann+HbwKmodP+OE8UCbsifQDYMLD5J3em1Cdn3MYPpbEd5elGDwmP98T+WbqP/tvzA5Mjg==", - "dev": true - } - } - }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha512-hdrFxZOycD/g6A6SoI2bB5NA/5NEqD0569+S47WZhPvm46sD50ZHdYaFmnua5lndde9rCHGjmfK7Z8BuCt/PcQ==", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - }, - "dependencies": { - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true - }, - "negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "dev": true - }, - "node-static": { - "version": "0.7.11", - "resolved": "https://registry.npmjs.org/node-static/-/node-static-0.7.11.tgz", - "integrity": "sha512-zfWC/gICcqb74D9ndyvxZWaI1jzcoHmf4UTHWQchBNuNMxdBLJMDiUgZ1tjGLEIe/BMhj2DxKD8HOuc2062pDQ==", - "dev": true, - "requires": { - "colors": ">=0.6.0", - "mime": "^1.2.9", - "optimist": ">=0.3.4" - } - }, - "npm-run-path": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-3.1.0.tgz", - "integrity": "sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg==", - "dev": true, - "requires": { - "path-key": "^3.0.0" - } - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha512-snN4O4TkigujZphWLN0E//nQmm7790RYaE53DdL7ZYwee2D8DDo9/EyYiKUfN3rneWUjhJnueija3G9I2i0h3g==", - "dev": true, - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - }, - "dependencies": { - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha512-iotkTvxc+TwOm5Ieim8VnSNvCDjCK9S8G3scJ50ZthspSxa7jx50jkhYduuAtAjvfDUwSgOwf8+If99AlOEhyw==", - "dev": true - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha512-1tMA907+V4QmxV7dbRvb4/8MaRALK6q9Abid3ndMYnbyo8piisCmeONVqVSXqQA3KaP4SLt5b7ud6E2sqP8TFw==", - "dev": true - } - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==", - "dev": true - }, - "p-finally": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz", - "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==", - "dev": true - }, - "p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "dev": true, - "requires": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - } - }, - "parents": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", - "integrity": "sha512-mXKF3xkoUt5td2DoxpLmtOmZvko9VfFpwRwkKDHSNvgmpLAeBo18YDhcPbBzJq+QLCHMbGOfzia2cX4U+0v9Mg==", - "dev": true, - "requires": { - "path-platform": "~0.11.15" - } - }, - "parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", - "dev": true, - "requires": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "path-platform": { - "version": "0.11.15", - "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", - "integrity": "sha512-Y30dB6rab1A/nfEKsZxmr01nUotHX0c/ZiIAsCTatEe1CmS5Pm5He7fZ195bPT7RdquoaL8lLxFCMQi/bS7IJg==", - "dev": true - }, - "pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", - "dev": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", - "dev": true - }, - "promise-retry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", - "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", - "dev": true, - "requires": { - "err-code": "^2.0.2", - "retry": "^0.12.0" - } - }, - "psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "pulp": { - "version": "16.0.2", - "resolved": "https://registry.npmjs.org/pulp/-/pulp-16.0.2.tgz", - "integrity": "sha512-dvLRBMP2q1hgsHm9xRGskWJdx/Q3fDugLEAlT1zJIKRP7x/EWirMDi31jAWmM7oLkKC+3EedJ7i9d9NHeSb87A==", - "dev": true, - "requires": { - "browserify": "^16.2.3", - "browserify-incremental": "^3.1.1", - "concat-stream": "^2.0.0", - "gaze": "^1.1.3", - "glob": "^7.1.3", - "mold-source-map": "^0.4.0", - "node-static": "^0.7.11", - "read": "^1.0.7", - "sorcery": "^0.10.0", - "temp": "^0.9.0", - "through": "^2.3.8", - "tree-kill": "^1.2.1", - "which": "^1.3.1", - "wordwrap": "1.0.0" - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", - "dev": true - }, - "purescript": { - "version": "0.15.4", - "resolved": "https://registry.npmjs.org/purescript/-/purescript-0.15.4.tgz", - "integrity": "sha512-6Ge3IMcIxKkOUXg91cBgvjbqu5SxdfwbvWi1P4g+E2maxfvDv+roWAmLyOteTsxQE4SEa/wWoCZvnZ/AEjvrMw==", - "dev": true, - "requires": { - "purescript-installer": "^0.2.6" - } - }, - "purescript-installer": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/purescript-installer/-/purescript-installer-0.2.6.tgz", - "integrity": "sha512-22un7k/S0hETctsMMVlCEuXlvy1VAgN/uL49B65dQVPUVd17fh9CbB5kd9xoqiADUyw3t5HgL68lCwmDwrCCVw==", - "dev": true, - "requires": { - "arch": "^2.1.1", - "byline": "^5.0.0", - "cacache": "^11.3.2", - "chalk": "^2.4.2", - "env-paths": "^2.2.0", - "execa": "^2.0.3", - "filesize": "^4.1.2", - "is-plain-obj": "^2.0.0", - "log-symbols": "^3.0.0", - "log-update": "^3.2.0", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "ms": "^2.1.2", - "once": "^1.4.0", - "pump": "^3.0.0", - "request": "^2.88.0", - "rimraf": "^2.6.3", - "semver": "^7.3.7", - "tar": "^4.4.6", - "which": "^1.3.1", - "zen-observable": "^0.8.14" - }, - "dependencies": { - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } - } - }, - "purescript-psa": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/purescript-psa/-/purescript-psa-0.8.2.tgz", - "integrity": "sha512-4Olf0aQQrNCfcDLXQI3gJgINEQ+3U+4QPLmQ2LHX2L/YOXSwM7fOGIUs/wMm/FQnwERUyQmHKQTJKB4LIjE2fg==", - "dev": true - }, - "purs-tidy": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/purs-tidy/-/purs-tidy-0.9.0.tgz", - "integrity": "sha512-7la7Jw5CyuMDXJMliGiK746xevUScDCTJ0eMvN/mV/NAQF2c9Cqa31QNx5O15ae2d7SuFDqEiVALFzHYD601Cg==", - "dev": true - }, - "qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", - "dev": true - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==", - "dev": true - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "read": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", - "integrity": "sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==", - "dev": true, - "requires": { - "mute-stream": "~0.0.4" - } - }, - "read-only-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz", - "integrity": "sha512-3ALe0bjBVZtkdWKIcThYpQCLbBMd/+Tbh2CDSrAIDO3UsZ4Xs+tnyjv2MjCOMMgBG+AsUOeuP1cgtY1INISc8w==", - "dev": true, - "requires": { - "readable-stream": "^2.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "dev": true, - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", - "dev": true, - "requires": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==", - "dev": true, - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - }, - "dependencies": { - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true - }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - } - } - }, - "retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", - "dev": true - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha512-ntymy489o0/QQplUDnpYAYUsO50K9SBrIVaKCWDOJzYJts0f9WH9RFJkyagebkw5+y1oi00R7ynNW/d12GBumg==", - "dev": true, - "requires": { - "aproba": "^1.1.1" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "sander": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/sander/-/sander-0.5.1.tgz", - "integrity": "sha512-3lVqBir7WuKDHGrKRDn/1Ye3kwpXaDOMsiRP1wd6wpZW56gJhsbp5RqQpA6JG/P+pkXizygnr1dKR8vzWaVsfA==", - "dev": true, - "requires": { - "es6-promise": "^3.1.2", - "graceful-fs": "^4.1.3", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.2" - }, - "dependencies": { - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } - } - }, - "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shasum": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/shasum/-/shasum-1.0.2.tgz", - "integrity": "sha512-UTzHm/+AzKfO9RgPgRpDIuMSNie1ubXRaljjlhFMNGYoG7z+rm9AHLPMf70R7887xboDH9Q+5YQbWKObFHEAtw==", - "dev": true, - "requires": { - "json-stable-stringify": "~0.0.0", - "sha.js": "~2.4.4" - } - }, - "shasum-object": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shasum-object/-/shasum-object-1.0.0.tgz", - "integrity": "sha512-Iqo5rp/3xVi6M4YheapzZhhGPVs0yZwHj7wvwQ1B9z8H6zk+FEnI7y3Teq7qwnekfEhu8WmG2z0z4iWZaxLWVg==", - "dev": true, - "requires": { - "fast-safe-stringify": "^2.0.7" - } - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "shell-quote": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.3.tgz", - "integrity": "sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==", - "dev": true - }, - "signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "dev": true - }, - "smart-buffer": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", - "dev": true - }, - "socks": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.0.tgz", - "integrity": "sha512-scnOe9y4VuiNUULJN72GrM26BNOjVsfPXI+j+98PkyEfsIXroa5ofyjT+FzGvn/xHs73U2JtoBYAVx9Hl4quSA==", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", "dev": true, - "requires": { - "ip": "^2.0.0", - "smart-buffer": "^4.2.0" + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" } }, - "socks-proxy-agent": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz", - "integrity": "sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==", + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", "dev": true, - "requires": { - "agent-base": "^6.0.2", - "debug": "^4.3.3", - "socks": "^2.6.2" - } + "license": "CC-BY-3.0" }, - "sorcery": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/sorcery/-/sorcery-0.10.0.tgz", - "integrity": "sha512-R5ocFmKZQFfSTstfOtHjJuAwbpGyf9qjQa1egyhvXSbM7emjrtLXtGdZsDJDABC85YBfVvrOiGWKSYXPKdvP1g==", + "node_modules/spdx-expression-parse": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz", + "integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==", "dev": true, - "requires": { - "buffer-crc32": "^0.2.5", - "minimist": "^1.2.0", - "sander": "^0.5.0", - "sourcemap-codec": "^1.3.0" + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" } }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "dev": true - }, - "sourcemap-codec": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", - "dev": true + "node_modules/spdx-license-ids": { + "version": "3.0.23", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.23.tgz", + "integrity": "sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==", + "dev": true, + "license": "CC0-1.0" }, - "spago": { - "version": "0.20.9", - "resolved": "https://registry.npmjs.org/spago/-/spago-0.20.9.tgz", - "integrity": "sha512-r5TUxnYn9HawlQyMswlhIk24BGFSN2KGbqgZFZrn47GjTpMscU14xkt9CqTWgoSQYsoZieG+3dUtOxUQ7GYD7w==", + "node_modules/ssh2": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/ssh2/-/ssh2-1.17.0.tgz", + "integrity": "sha512-wPldCk3asibAjQ/kziWQQt1Wh3PgDFpC0XpwclzKcdT1vql6KeYxf5LIt4nlFkUeR8WuphYMKqUA56X4rjbfgQ==", "dev": true, - "requires": { - "make-fetch-happen": "^9.1.0", - "tar": "^6.1.11" - }, + "hasInstallScript": true, "dependencies": { - "chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true - }, - "fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - }, - "tar": { - "version": "6.1.11", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", - "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", - "dev": true, - "requires": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } + "asn1": "^0.2.6", + "bcrypt-pbkdf": "^1.0.2" + }, + "engines": { + "node": ">=10.16.0" + }, + "optionalDependencies": { + "cpu-features": "~0.0.10", + "nan": "^2.23.0" } }, - "sshpk": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", - "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", - "dev": true, - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, - "ssri": { + "node_modules/ssri": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz", "integrity": "sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==", "dev": true, - "requires": { + "license": "ISC", + "dependencies": { "figgy-pudding": "^3.5.1" } }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - } - }, - "stream-combiner2": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", - "integrity": "sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw==", - "dev": true, - "requires": { - "duplexer2": "~0.1.0", - "readable-stream": "^2.0.2" - } - }, - "stream-each": { + "node_modules/stream-each": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "end-of-stream": "^1.1.0", "stream-shift": "^1.0.0" } }, - "stream-http": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz", - "integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "xtend": "^4.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "stream-splicer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.1.tgz", - "integrity": "sha512-Xizh4/NPuYSyAXyT7g8IvdJ9HJpxIGL9PjyhtywCZvvP0OPIdqyrr4dMikeuvY8xahpdKEBlBTySe583totajg==", + "node_modules/stream-shift": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", + "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==", "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.2" - } + "license": "MIT" }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, - "requires": { - "safe-buffer": "~5.2.0" + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" } }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" } }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, - "requires": { - "ansi-regex": "^4.1.0" + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, - "strip-final-newline": { + "node_modules/strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true - }, - "subarg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", - "integrity": "sha512-RIrIdRY0X1xojthNcVtgT9sjpOGagEUKpZdgBUi054OEPFo282yg+zE+t1Rj3+RqKq2xStL7uUHhY+AjbC4BXg==", "dev": true, - "requires": { - "minimist": "^1.1.0" + "license": "MIT", + "engines": { + "node": ">=6" } }, - "supports-color": { + "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true + "node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "deprecated": "Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } }, - "syntax-error": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.4.0.tgz", - "integrity": "sha512-YPPlu67mdnHGTup2A8ff7BC2Pjq0e0Yp/IyTFN03zWO0RcK07uLcbi7C2KpGR2FvWbaB0+bfE27a+sBKebSo7w==", + "node_modules/tar/node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", "dev": true, - "requires": { - "acorn-node": "^1.2.0" + "license": "ISC", + "engines": { + "node": ">=10" } }, - "tar": { - "version": "4.4.19", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", - "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", "dev": true, - "requires": { - "chownr": "^1.1.4", - "fs-minipass": "^1.2.7", - "minipass": "^2.9.0", - "minizlib": "^1.3.3", - "mkdirp": "^0.5.5", - "safe-buffer": "^5.2.1", - "yallist": "^3.1.1" - }, - "dependencies": { - "minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", - "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", - "dev": true, - "requires": { - "minipass": "^2.9.0" - } - } + "license": "ISC", + "engines": { + "node": ">=8" } }, - "temp": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/temp/-/temp-0.9.4.tgz", - "integrity": "sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA==", + "node_modules/tar/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true, - "requires": { - "mkdirp": "^0.5.1", - "rimraf": "~2.6.2" + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" }, - "dependencies": { - "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } + "engines": { + "node": ">=10" } }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true + "node_modules/tar/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" }, - "through2": { + "node_modules/through2": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "readable-stream": "~2.3.6", "xtend": "~4.0.1" } }, - "timers-browserify": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz", - "integrity": "sha512-PIxwAupJZiYU4JmVZYwXp9FKsHMXb5h0ZEFyuXTAn8WLHOlcij+FEcbrvDsom1o5dr1YggEtFbECvGCW2sT53Q==", + "node_modules/tmp": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.7.tgz", + "integrity": "sha512-e0votIpp4Uo2AJYSzVHV6xCcawuiez3DzqDAbrTc3YxBkplN6e+dM13ZeIcZnDg/QpSuU2zfZ3rzwY8ukEnaXw==", "dev": true, - "requires": { - "process": "~0.11.0" + "license": "MIT", + "engines": { + "node": ">=14.14" } }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, + "license": "MIT", "dependencies": { - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - } - } - }, - "tree-kill": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", - "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", - "dev": true - }, - "tty-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", - "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", - "dev": true - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" } }, - "tweetnacl": { + "node_modules/tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true + "dev": true, + "license": "Unlicense" + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "typedarray": { + "node_modules/typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true - }, - "umd": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.3.tgz", - "integrity": "sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow==", - "dev": true + "dev": true, + "license": "MIT" }, - "undeclared-identifiers": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/undeclared-identifiers/-/undeclared-identifiers-1.1.3.tgz", - "integrity": "sha512-pJOW4nxjlmfwKApE4zvxLScM/njmwj/DiUBv7EabwE4O8kRUy+HIwxQtZLBPll/jx1LJyBcqNfB3/cpv9EZwOw==", + "node_modules/uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", "dev": true, - "requires": { - "acorn-node": "^1.3.0", - "dash-ast": "^1.0.0", - "get-assigned-identifiers": "^1.2.0", - "simple-concat": "^1.0.0", - "xtend": "^4.0.1" - } + "license": "MIT" }, - "unique-filename": { + "node_modules/unique-filename": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", "dev": true, - "requires": { + "license": "ISC", + "dependencies": { "unique-slug": "^2.0.0" } }, - "unique-slug": { + "node_modules/unique-slug": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", "dev": true, - "requires": { + "license": "ISC", + "dependencies": { "imurmurhash": "^0.1.4" } }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, - "requires": { - "punycode": "^2.1.0" - }, - "dependencies": { - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - } + "license": "MIT", + "engines": { + "node": ">= 10.0.0" } }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==", + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, + "license": "MIT" + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "license": "ISC", "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==", - "dev": true - } + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" } }, - "util": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", - "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, - "requires": { - "inherits": "2.0.3" - }, + "license": "MIT", "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", - "dev": true - } + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" } }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - }, + "license": "MIT", "dependencies": { - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "dev": true - } + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "requires": { - "isexe": "^2.0.0" + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "dev": true - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } + "license": "MIT" }, - "wrappy": { + "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "dev": true, + "license": "ISC" + }, + "node_modules/wsl-utils": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz", + "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/xhr2": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/xhr2/-/xhr2-0.2.1.tgz", + "integrity": "sha512-sID0rrVCqkVNUn8t6xuv9+6FViXjUVXq8H5rWOH2rz9fDNQEd4g0EA2XlcEdJXRz5BMEn4O1pJFdT+z4YHhoWw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } }, - "xtend": { + "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4" + } }, - "y18n": { + "node_modules/y18n": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true + "dev": true, + "license": "ISC" }, - "yallist": { + "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "dev": true, + "license": "ISC" + }, + "node_modules/yaml": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", + "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } }, - "zen-observable": { + "node_modules/zen-observable": { "version": "0.8.15", "resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.15.tgz", "integrity": "sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==", - "dev": true + "dev": true, + "license": "MIT" } } } diff --git a/package.json b/package.json index 83e12a8..921c34f 100644 --- a/package.json +++ b/package.json @@ -1,23 +1,20 @@ { "name": "purescript-react-halo", - "version": "1.0.0", - "description": "", - "main": "index.js", + "version": "4.0.0", + "description": "Scoped action handling and application effects for PureScript React components", "scripts": { "build": "spago build", - "docs": "rimraf ./output/React.Halo.* && spago docs --format markdown", - "postinstall": "spago install", - "test": "spago test --config ./spago.test.dhall" + "format": "npx --yes purs-tidy@0.11.1 format-in-place src test", + "format:check": "npx --yes purs-tidy@0.11.1 check src test", + "test": "spago test" }, - "author": "", - "license": "ISC", + "repository": { + "type": "git", + "url": "https://github.com/robertdp/purescript-react-halo.git" + }, + "license": "BSD-3-Clause", "devDependencies": { - "bower": "^1.8.14", - "pulp": "^16.0.2", - "purescript": "^0.15.4", - "purescript-psa": "^0.8.2", - "purs-tidy": "^0.9.0", - "rimraf": "^3.0.2", - "spago": "^0.20.9" + "purescript": "0.15.16", + "spago": "1.0.4" } } diff --git a/packages.dhall b/packages.dhall deleted file mode 100644 index 30d8b94..0000000 --- a/packages.dhall +++ /dev/null @@ -1,5 +0,0 @@ -let upstream = - https://github.com/purescript/package-sets/releases/download/psc-0.15.4-20220718/packages.dhall - sha256:a6d66723b6109f1e3eaf6575910f1c51aa545965ce313024ba329360e2f009ac - -in upstream diff --git a/spago.dhall b/spago.dhall deleted file mode 100644 index e574b52..0000000 --- a/spago.dhall +++ /dev/null @@ -1,27 +0,0 @@ -{ name = "react-halo" -, license = "BSD-3-Clause" -, repository = "https://github.com/robertdp/purescript-react-halo.git" -, dependencies = - [ "aff" - , "bifunctors" - , "effect" - , "either" - , "foldable-traversable" - , "free" - , "freeap" - , "halogen-subscriptions" - , "maybe" - , "newtype" - , "ordered-collections" - , "parallel" - , "prelude" - , "react-basic-hooks" - , "refs" - , "tailrec" - , "transformers" - , "tuples" - , "unsafe-reference" - ] -, packages = ./packages.dhall -, sources = [ "src/**/*.purs" ] -} diff --git a/spago.lock b/spago.lock new file mode 100644 index 0000000..b516492 --- /dev/null +++ b/spago.lock @@ -0,0 +1,1951 @@ +{ + "workspace": { + "packages": { + "react-halo": { + "path": "./", + "core": { + "dependencies": [ + "aff", + "avar", + "effect", + "either", + "exceptions", + "foldable-traversable", + "maybe", + "newtype", + "ordered-collections", + "parallel", + "prelude", + "profunctor-lenses", + "react-basic-hooks", + "refs", + "transformers", + "tuples", + "unsafe-reference" + ] + }, + "test": { + "dependencies": [ + "console", + "control", + "exceptions", + "react-basic-dom", + "spec", + "spec-node" + ] + } + } + }, + "package_set": { + "address": { + "registry": "80.8.0" + }, + "compiler": ">=0.15.15 <0.16.0", + "content": { + "abc-parser": "2.1.0", + "ace": "9.1.0", + "address-rfc2821": "0.1.1", + "aff": "8.0.0", + "aff-bus": "6.0.0", + "aff-coroutines": "9.0.0", + "aff-promise": "4.0.0", + "aff-retry": "2.0.0", + "affjax": "13.0.0", + "affjax-node": "1.0.0", + "affjax-web": "1.0.0", + "ansi": "7.0.0", + "apexcharts": "0.5.0", + "applicative-phases": "1.0.0", + "argonaut": "9.0.0", + "argonaut-aeson-generic": "0.4.1", + "argonaut-codecs": "9.1.0", + "argonaut-core": "7.0.0", + "argonaut-generic": "8.0.0", + "argonaut-traversals": "10.0.0", + "argparse-basic": "2.0.0", + "array-builder": "0.1.2", + "array-search": "0.6.0", + "arraybuffer": "13.2.0", + "arraybuffer-builder": "3.1.0", + "arraybuffer-types": "3.0.2", + "arrays": "7.3.0", + "arrays-extra": "0.6.2", + "arrays-zipper": "2.0.1", + "ask": "1.0.0", + "assert": "6.0.0", + "assert-multiple": "0.4.0", + "avar": "5.0.1", + "axon": "0.0.3", + "b64": "0.0.9", + "barbies": "1.0.1", + "barlow-lens": "1.0.0", + "baskerville-core": "0.1.3", + "baskerville-mycroft": "0.1.0", + "benchlib": "0.0.4", + "bifunctors": "6.1.0", + "bigints": "7.0.1", + "blessed": "1.0.0", + "bolson": "0.3.9", + "bookhound": "0.1.7", + "bower-json": "3.0.0", + "bytestrings": "9.0.0", + "call-by-name": "4.0.1", + "canvas": "6.0.0", + "canvas-action": "9.0.0", + "cartesian": "1.0.6", + "catenable-lists": "7.0.0", + "cbor-stream": "1.3.0", + "chameleon": "1.0.0", + "chameleon-halogen": "1.0.3", + "chameleon-react-basic": "1.1.0", + "chameleon-styled": "2.5.0", + "chameleon-transformers": "1.0.0", + "channel": "1.0.0", + "chartjs": "0.2.0", + "chartjs-halogen": "0.2.0", + "checked-exceptions": "3.1.1", + "choku": "1.0.2", + "classless": "0.1.1", + "classless-arbitrary": "0.1.1", + "classless-decode-json": "0.1.1", + "classless-encode-json": "0.1.3", + "classnames": "2.0.0", + "codec": "6.1.0", + "codec-argonaut": "10.0.0", + "codec-json": "2.0.0", + "colors": "7.0.1", + "compile-fail": "0.4.0", + "concur-core": "0.5.0", + "concur-react": "0.5.0", + "concurrent-queues": "3.0.0", + "console": "6.1.0", + "const": "6.0.0", + "contravariant": "6.0.0", + "control": "6.0.0", + "convertable-options": "1.0.0", + "coroutines": "7.0.0", + "css": "6.0.0", + "css-class-name-extractor": "0.0.4", + "css-frameworks": "1.1.0", + "csv-stream": "2.3.0", + "currency": "0.1.0", + "data-mvc": "0.0.2", + "datetime": "6.1.0", + "datetime-parsing": "0.2.0", + "debounce": "0.1.2", + "debug": "6.0.2", + "decimals": "7.1.0", + "default-values": "1.0.1", + "deku": "0.9.24", + "deno": "0.0.5", + "dissect": "1.0.0", + "distributive": "6.0.0", + "dodo-printer": "2.2.3", + "dom-filereader": "7.0.0", + "dom-indexed": "13.0.0", + "dom-simple": "0.4.0", + "dotenv": "4.0.3", + "droplet": "0.6.0", + "dts": "1.0.0", + "dual-numbers": "1.0.3", + "dynamic-buffer": "3.0.1", + "echarts-simple": "0.0.1", + "effect": "4.0.0", + "either": "6.1.0", + "elmish": "0.15.0", + "elmish-enzyme": "0.1.1", + "elmish-hooks": "0.12.0", + "elmish-html": "0.14.0", + "elmish-testing-library": "0.5.0", + "email-validate": "7.0.0", + "encoding": "0.0.10", + "enums": "6.0.1", + "env-names": "0.4.0", + "environment": "2.0.0", + "error": "2.0.0", + "eta-conversion": "0.3.2", + "exceptions": "6.1.0", + "exists": "6.0.0", + "exitcodes": "4.0.0", + "expect-inferred": "3.0.0", + "express": "0.9.1", + "ezfetch": "1.1.1", + "fahrtwind": "2.0.0", + "faker-ffi": "0.1.1", + "fakerjs": "0.0.1", + "fallback": "0.1.0", + "fast-vect": "1.2.0", + "fetch": "4.1.0", + "fetch-argonaut": "1.0.1", + "fetch-core": "5.1.0", + "fetch-yoga-json": "1.1.0", + "ffi-simple": "0.5.1", + "fft": "0.3.0", + "fft-js": "0.1.0", + "filterable": "5.0.0", + "fix-functor": "0.1.0", + "fixed-points": "7.0.0", + "fixed-precision": "5.0.0", + "flame": "1.6.0", + "float32": "2.0.0", + "fmt": "0.2.1", + "foldable-traversable": "6.0.0", + "foldable-traversable-extra": "0.0.6", + "foreign": "7.0.0", + "foreign-object": "4.1.0", + "foreign-readwrite": "3.4.0", + "forgetmenot": "0.1.0", + "fork": "6.0.0", + "form-urlencoded": "7.0.0", + "formatters": "7.0.0", + "framer-motion": "3.1.0", + "free": "7.1.0", + "freeap": "7.0.0", + "freer-free": "0.0.1", + "freet": "7.0.0", + "functions": "6.0.0", + "functor1": "3.0.0", + "functors": "5.0.0", + "fuzzy": "0.4.0", + "gen": "4.0.0", + "generate-values": "1.0.1", + "generic-router": "0.0.1", + "geojson": "0.0.5", + "geometria": "2.2.0", + "gesso": "1.0.1", + "gojs": "0.1.1", + "golden-test": "0.1.0", + "golem-fetch": "0.1.0", + "grain": "3.0.0", + "grain-router": "3.0.0", + "grain-virtualized": "3.0.0", + "graphql-client": "10.1.1", + "graphs": "8.1.0", + "group": "4.1.1", + "halogen": "7.0.0", + "halogen-bootstrap5": "5.3.2", + "halogen-canvas": "1.0.0", + "halogen-css": "10.0.0", + "halogen-declarative-canvas": "0.0.8", + "halogen-echarts-simple": "0.0.4", + "halogen-formless": "4.0.3", + "halogen-helix": "1.1.0", + "halogen-hooks": "0.6.3", + "halogen-hooks-extra": "0.9.0", + "halogen-infinite-scroll": "1.1.0", + "halogen-store": "0.5.4", + "halogen-storybook": "2.0.0", + "halogen-subscriptions": "2.0.0", + "halogen-svg-elems": "8.0.0", + "halogen-typewriter": "1.0.4", + "halogen-use-trigger-hooks": "1.0.0", + "halogen-vdom": "8.0.0", + "halogen-vdom-string-renderer": "0.5.0", + "halogen-widgets": "0.3.1", + "halogen-xterm": "2.0.0", + "harmonia": "0.2.0", + "heckin": "2.0.1", + "heterogeneous": "0.7.0", + "homogeneous": "0.4.0", + "http-methods": "6.1.0", + "httpurple": "4.0.0", + "huffman": "0.4.0", + "humdrum": "0.0.1", + "hylograph-canvas": "0.1.0", + "hylograph-components": "0.1.0", + "hylograph-d3-kernel": "0.1.0", + "hylograph-graph": "0.3.0", + "hylograph-layout": "0.3.0", + "hylograph-music": "0.4.0", + "hylograph-optics": "0.1.0", + "hylograph-selection": "0.5.3", + "hylograph-simulation": "0.6.0", + "hylograph-simulation-core": "0.1.0", + "hylograph-simulation-halogen": "0.5.1", + "hylograph-transitions": "0.1.0", + "hylograph-wasm-kernel": "0.1.0", + "hyrule": "2.3.9", + "i18next": "0.1.0", + "idb": "0.2.0", + "identity": "6.0.0", + "identy": "4.0.1", + "indexed-db": "1.0.0", + "indexed-monad": "3.0.0", + "ink": "0.0.1", + "int64": "3.0.0", + "integers": "6.0.0", + "interpolate": "5.0.2", + "intersection-observer": "1.0.1", + "invariant": "6.0.0", + "jarilo": "1.0.1", + "jelly": "0.10.0", + "jelly-router": "0.3.0", + "jelly-signal": "0.4.0", + "jest": "1.0.0", + "js-abort-controller": "1.0.0", + "js-bigints": "2.2.1", + "js-date": "8.0.0", + "js-fetch": "0.2.1", + "js-fileio": "3.0.0", + "js-intl": "1.3.0", + "js-iterators": "0.1.1", + "js-maps": "0.1.2", + "js-promise": "1.0.0", + "js-promise-aff": "1.0.0", + "js-temporal": "3.0.0", + "js-timers": "6.1.0", + "js-uri": "3.1.0", + "jsdom": "1.0.0", + "jsinc": "0.5.1", + "json": "1.1.0", + "json-codecs": "5.0.0", + "justifill": "0.5.0", + "jwt": "0.0.9", + "labeled-data": "0.2.0", + "language-cst-parser": "0.14.1", + "lazy": "6.0.0", + "lazy-joe": "1.0.0", + "lcg": "4.0.0", + "leibniz": "5.0.0", + "leveldb": "1.0.1", + "liminal": "1.0.1", + "linalg": "6.0.0", + "linear": "0.1.0", + "lists": "7.0.0", + "literals": "1.0.2", + "logging": "3.0.0", + "logging-journald": "0.4.0", + "lumi-components": "18.0.0", + "machines": "7.0.0", + "maps-eager": "0.5.0", + "marionette": "1.0.0", + "marionette-react-basic-hooks": "0.1.1", + "markdown-it-js": "0.1.0", + "marked": "0.1.0", + "matrices": "5.0.1", + "matryoshka": "1.0.0", + "maybe": "6.0.0", + "media-types": "6.0.0", + "meowclient": "1.0.0", + "midi": "4.0.0", + "milkdown": "0.1.0", + "milkis": "9.0.0", + "mimetype": "0.0.1", + "minibench": "4.0.1", + "mmorph": "7.0.0", + "monad-control": "5.0.0", + "monad-logger": "1.3.1", + "monad-loops": "0.5.0", + "monad-unlift": "1.0.1", + "monoid-extras": "0.0.1", + "monoidal": "0.16.0", + "mote": "3.0.0", + "motion": "4.0.0", + "motsunabe": "2.0.0", + "mvc": "0.0.1", + "mycroft": "0.1.1", + "mycroft-z3-wasm": "0.1.0", + "mysql": "6.0.1", + "n3": "0.1.0", + "nano-id": "1.1.0", + "nanoid": "0.1.0", + "naturals": "3.0.0", + "nested-functor": "0.2.1", + "newtype": "5.0.0", + "next-purs-rsc": "0.1.0", + "nextjs": "0.1.1", + "nextui": "0.2.0", + "node-buffer": "9.0.0", + "node-child-process": "11.1.0", + "node-event-emitter": "3.0.0", + "node-execa": "5.0.0", + "node-fs": "9.2.0", + "node-glob-basic": "2.0.0", + "node-http": "9.1.0", + "node-http2": "1.1.1", + "node-human-signals": "1.0.0", + "node-net": "5.1.0", + "node-os": "5.1.0", + "node-path": "5.0.1", + "node-process": "11.2.0", + "node-readline": "8.1.1", + "node-sqlite": "0.2.0", + "node-sqlite3": "8.0.0", + "node-stream-pipes": "2.1.6", + "node-streams": "9.0.1", + "node-tls": "0.3.1", + "node-url": "7.0.1", + "node-workerbees": "0.3.1", + "node-zlib": "0.4.0", + "nonempty": "7.0.0", + "now": "6.0.0", + "npm-package-json": "2.0.0", + "nqueens": "0.1.4", + "nullable": "6.0.0", + "numberfield": "0.2.2", + "numbers": "9.0.1", + "oak": "3.1.1", + "oak-debug": "1.2.2", + "object-maps": "0.3.0", + "ocarina": "1.5.4", + "oooooooooorrrrrrrmm-lib": "0.0.1", + "open-colors-scales-and-schemes": "1.0.0", + "open-drawing": "6.0.4", + "open-folds": "6.4.0", + "open-foreign-generic": "11.0.3", + "open-memoize": "6.2.0", + "open-mkdirp-aff": "1.2.0", + "open-pairing": "6.2.0", + "open-smolder": "12.0.2", + "options": "7.0.0", + "optparse": "5.0.1", + "ordered-collections": "3.2.0", + "ordered-set": "0.5.2", + "orders": "6.0.0", + "org-doc": "0.1.0", + "owoify": "1.2.0", + "pairs": "9.0.1", + "parallel": "7.0.0", + "parsing": "11.0.0", + "parsing-dataview": "3.2.4", + "partial": "4.0.0", + "pathy": "9.0.0", + "pha": "0.13.0", + "phaser": "0.7.0", + "phylio": "1.1.2", + "pipes": "8.0.0", + "pirates-charm": "0.0.1", + "play": "1.0.0", + "pmock": "0.9.0", + "point-free": "1.0.0", + "pointed-list": "0.5.1", + "polymorphic-vectors": "4.0.0", + "posix-types": "6.0.0", + "postgresql": "2.0.21", + "precise": "6.0.0", + "precise-datetime": "7.0.0", + "prelude": "6.0.2", + "prettier-printer": "3.0.0", + "printf": "0.1.0", + "priority-queue": "0.1.2", + "profunctor": "6.0.1", + "profunctor-lenses": "8.0.0", + "prospero": "0.1.0", + "protobuf": "4.4.0", + "ps-spa": "0.7.1", + "psa-utils": "8.0.0", + "psci-support": "6.0.0", + "punycode": "1.0.0", + "pursfmt": "0.17.0", + "qualified-do": "2.2.0", + "quantities": "12.2.0", + "quickcheck": "8.0.1", + "quickcheck-combinators": "0.1.3", + "quickcheck-laws": "7.0.0", + "quickcheck-utf8": "0.0.0", + "random": "6.0.0", + "rationals": "6.0.0", + "rdf": "0.1.0", + "react": "11.0.0", + "react-aria": "0.2.0", + "react-basic": "17.0.0", + "react-basic-classic": "3.0.0", + "react-basic-dnd": "10.1.0", + "react-basic-dom": "7.0.0", + "react-basic-dom-beta": "0.1.1", + "react-basic-emotion": "7.1.0", + "react-basic-hooks": "9.1.1", + "react-basic-storybook": "2.0.0", + "react-dnd-kit": "0.6.0", + "react-dom": "8.0.0", + "react-halo": "3.0.0", + "react-icons": "1.1.6", + "react-markdown": "0.1.0", + "react-testing-library": "4.0.1", + "react-virtuoso": "1.0.0", + "reactix": "0.6.1", + "read": "1.0.1", + "recharts": "1.1.0", + "record": "4.0.0", + "record-extra": "5.0.1", + "record-extra-srghma": "0.2.8", + "record-ptional-fields": "0.1.2", + "record-studio": "1.0.4", + "ref-lifted": "0.0.2", + "refs": "6.0.0", + "remotedata": "5.0.1", + "repr": "0.5.0", + "resize-arrays": "0.0.1", + "resize-observer": "1.0.0", + "resource": "2.0.1", + "resourcet": "1.0.0", + "result": "1.0.3", + "return": "0.2.0", + "ring-modules": "5.0.1", + "rito": "0.3.4", + "roman": "0.4.0", + "rough-notation": "1.0.2", + "routing": "11.0.0", + "routing-duplex": "0.7.0", + "run": "5.0.0", + "safe-coerce": "2.0.0", + "safely": "4.0.1", + "school-of-music": "1.3.0", + "selection-foldable": "0.2.0", + "selective-functors": "1.0.1", + "semirings": "7.0.0", + "shuffle": "2.0.0", + "sigil": "0.3.0", + "sigil-hats": "0.3.0", + "signal": "13.0.0", + "simple-emitter": "3.0.1", + "simple-i18n": "2.0.1", + "simple-json": "9.0.0", + "simple-json-generics": "0.2.1", + "simple-ulid": "3.0.0", + "sized-matrices": "1.0.0", + "sized-vectors": "5.0.2", + "slug": "3.2.0", + "small-ffi": "4.0.1", + "soundfonts": "4.1.0", + "sparse-matrices": "2.0.1", + "sparse-polynomials": "3.0.1", + "spec": "8.1.2", + "spec-discovery": "8.4.1", + "spec-mocha": "5.1.1", + "spec-node": "0.0.3", + "spec-quickcheck": "5.0.2", + "spec-reporter-xunit": "0.7.1", + "splitmix": "2.1.0", + "ssrs": "1.0.0", + "st": "6.2.0", + "statistics": "0.3.2", + "strictlypositiveint": "1.0.1", + "string-parsers": "8.0.0", + "strings": "6.0.1", + "strings-extra": "4.0.0", + "stringutils": "0.0.13", + "structured-logging": "1.0.0", + "substitute": "0.2.3", + "supabase": "0.1.0", + "supply": "0.2.0", + "svg-parser": "3.0.0", + "systemd-journald": "0.3.0", + "tagged": "4.0.2", + "tailrec": "6.1.0", + "tanstack-query": "3.0.0", + "tecton": "0.2.1", + "tecton-halogen": "0.2.0", + "temporal": "0.2.0", + "test-unit": "17.0.0", + "text-formatting": "0.1.0", + "thermite": "6.3.1", + "thermite-dom": "0.3.1", + "these": "6.0.0", + "threading": "0.0.3", + "tidy": "0.11.1", + "tidy-codegen": "4.0.1", + "tldr": "0.0.0", + "toestand": "0.9.0", + "transformation-matrix": "1.0.1", + "transformers": "6.1.0", + "transit": "1.0.0", + "tree-rose": "4.0.2", + "trivial-unfold": "0.5.0", + "ts-bridge": "4.0.0", + "tuples": "7.0.0", + "two-or-more": "1.0.0", + "type-equality": "4.0.1", + "typedenv": "2.0.1", + "typelevel": "6.0.0", + "typelevel-lists": "2.1.0", + "typelevel-peano": "1.0.1", + "typelevel-prelude": "7.0.0", + "typelevel-regex": "0.0.3", + "typelevel-rows": "0.1.0", + "typisch": "0.4.0", + "uint": "7.0.0", + "ulid": "3.0.1", + "uncurried-transformers": "1.1.0", + "undefined": "2.0.0", + "undefined-is-not-a-problem": "1.1.0", + "unfoldable": "6.0.0", + "unicode": "6.0.0", + "unique": "0.6.1", + "unlift": "1.0.1", + "unordered-collections": "3.1.0", + "unsafe-coerce": "6.0.0", + "unsafe-reference": "5.0.0", + "untagged-to-tagged": "0.1.4", + "untagged-union": "1.0.0", + "uri": "9.0.0", + "url-immutable": "1.0.0", + "url-regex-safe": "0.1.1", + "uuid": "9.0.0", + "uuidv4": "1.0.0", + "validation": "6.0.0", + "variant": "8.0.0", + "variant-encodings": "2.0.0", + "variant-gen": "1.0.0", + "vectorfield": "1.0.1", + "vectors": "2.1.0", + "versions": "7.0.0", + "visx": "0.0.2", + "vitest": "2.0.1", + "wasm-base": "0.2.0", + "web-chain": "1.0.1", + "web-clipboard": "6.0.0", + "web-cssom": "2.0.0", + "web-cssom-view": "0.1.0", + "web-dom": "6.0.0", + "web-dom-parser": "8.0.0", + "web-dom-xpath": "3.0.0", + "web-encoding": "3.0.0", + "web-events": "4.0.0", + "web-fetch": "4.0.1", + "web-file": "4.0.0", + "web-geometry": "0.1.0", + "web-html": "4.1.1", + "web-pointerevents": "2.0.0", + "web-proletarian": "1.0.0", + "web-promise": "3.2.0", + "web-resize-observer": "2.1.0", + "web-router": "1.0.0", + "web-socket": "4.0.0", + "web-storage": "5.0.0", + "web-streams": "4.0.0", + "web-touchevents": "4.0.0", + "web-uievents": "5.0.0", + "web-url": "2.0.0", + "web-workers": "2.0.0", + "web-xhr": "5.0.1", + "webb-aff-list": "0.0.2", + "webb-array": "0.0.2", + "webb-channel": "0.0.3", + "webb-commandline": "0.0.3", + "webb-directory": "0.0.7", + "webb-file": "0.0.1", + "webb-map": "0.0.1", + "webb-monad": "0.0.2", + "webb-mutex": "0.0.7", + "webb-parsing": "0.0.5", + "webb-random": "0.0.1", + "webb-refer": "0.0.3", + "webb-set": "0.0.1", + "webb-slot": "0.0.1", + "webb-stateful": "0.0.3", + "webb-string": "0.0.1", + "webb-test": "0.0.1", + "webb-thread": "0.0.2", + "webb-writer": "0.0.3", + "webextension-polyfill": "0.1.0", + "webgpu": "0.0.1", + "which": "2.0.0", + "whine-core": "0.0.34", + "xterm": "1.0.0", + "yaml-next": "3.1.1", + "yoga-acp-om": "0.1.1", + "yoga-better-auth": "0.2.2", + "yoga-bun-yoga": "0.2.1", + "yoga-config": "0.2.1", + "yoga-country": "3.0.0", + "yoga-docker-compose": "0.1.1", + "yoga-dynamodb": "0.1.1", + "yoga-elasticsearch": "0.1.1", + "yoga-fastify": "0.5.4", + "yoga-fastify-om": "0.4.7", + "yoga-fetch": "1.0.1", + "yoga-fetch-om": "0.8.0", + "yoga-format": "1.0.0", + "yoga-heroui": "2.0.3", + "yoga-http-api": "0.3.4", + "yoga-jaeger": "0.1.1", + "yoga-json": "5.2.1", + "yoga-language": "1.0.0", + "yoga-next-fastify": "0.2.0", + "yoga-om": "2.2.1", + "yoga-om-layer": "2.1.0", + "yoga-om-strom": "0.4.3", + "yoga-om-workerbees": "0.1.2", + "yoga-opentelemetry": "0.2.0", + "yoga-options": "0.1.1", + "yoga-pino": "0.1.1", + "yoga-postgres": "6.0.0", + "yoga-react": "1.0.2", + "yoga-react-dom": "2.0.1", + "yoga-react-native": "0.2.1", + "yoga-react-om": "0.2.0", + "yoga-redis": "0.1.1", + "yoga-scylladb": "0.1.1", + "yoga-shadcn": "1.0.5", + "yoga-sql-types": "0.2.0", + "yoga-sqlite": "0.3.4", + "yoga-sqlite-om": "0.3.0", + "yoga-sse": "0.1.1", + "yoga-subtlecrypto": "0.1.0", + "yoga-test-docker": "0.1.2", + "yoga-timezone": "1.0.0", + "yoga-tree": "1.0.0", + "yoga-tree-svg": "0.1.0", + "yoga-tree-utils": "1.0.0", + "z3": "0.0.2", + "zipperarray": "2.0.0" + } + }, + "extra_packages": {} + }, + "packages": { + "aff": { + "type": "registry", + "version": "8.0.0", + "integrity": "sha256-9BRIrSdRoYybfiUmBqgKJ66cPqxYHb277bVWQMn/9sg=", + "dependencies": [ + "control", + "datetime", + "effect", + "either", + "exceptions", + "functions", + "newtype", + "parallel", + "partial", + "prelude", + "st", + "tailrec", + "transformers", + "unsafe-coerce" + ] + }, + "aff-promise": { + "type": "registry", + "version": "4.0.0", + "integrity": "sha256-Jgp3y+NWuuAmwz2V3LlWoX+AvxqfVglY77N5zTw8xnI=", + "dependencies": [ + "aff", + "control", + "effect", + "either", + "exceptions", + "foreign", + "prelude", + "transformers" + ] + }, + "ansi": { + "type": "registry", + "version": "7.0.0", + "integrity": "sha256-tOUaXJFzPSfBVAqLI8hc+Tz2M1rg16cXqyHaK/3SmFg=", + "dependencies": [ + "foldable-traversable", + "lists", + "prelude" + ] + }, + "argonaut-codecs": { + "type": "registry", + "version": "9.1.0", + "integrity": "sha256-K910SBrmYallESsm8pxJYThs7lig6hxX3M4PW33Cgew=", + "dependencies": [ + "argonaut-core", + "arrays", + "bifunctors", + "either", + "foldable-traversable", + "foreign-object", + "identity", + "integers", + "lists", + "maybe", + "nonempty", + "ordered-collections", + "prelude", + "record", + "strings", + "tuples" + ] + }, + "argonaut-core": { + "type": "registry", + "version": "7.0.0", + "integrity": "sha256-gYZihtBIKthVuXXoiPphMookSf8M5aHyFYkcIWqlxTM=", + "dependencies": [ + "arrays", + "control", + "either", + "foreign-object", + "functions", + "gen", + "maybe", + "nonempty", + "prelude", + "strings", + "tailrec" + ] + }, + "arraybuffer-types": { + "type": "registry", + "version": "3.0.2", + "integrity": "sha256-p05cJnSkyeoB7VHzMyc2Eb1RwUaB7Nl0sQSqEGNEUD8=", + "dependencies": [] + }, + "arrays": { + "type": "registry", + "version": "7.3.0", + "integrity": "sha256-GD4z7LCi9wzi7FCQqbWhvs8paoUK9NO+HwgXZ+KP8Rk=", + "dependencies": [ + "bifunctors", + "control", + "foldable-traversable", + "functions", + "maybe", + "nonempty", + "partial", + "prelude", + "safe-coerce", + "st", + "tailrec", + "tuples", + "unfoldable", + "unsafe-coerce" + ] + }, + "avar": { + "type": "registry", + "version": "5.0.1", + "integrity": "sha256-8V4SxF4TIWZ9Ik1P4lPzIRUAZeFBe8w5WA2VcCEKsIk=", + "dependencies": [ + "aff", + "effect", + "either", + "exceptions", + "functions", + "maybe", + "prelude" + ] + }, + "bifunctors": { + "type": "registry", + "version": "6.1.0", + "integrity": "sha256-CvZRb8uI75eKIqiYntR+k05Wk6tKlMS5w8sCA2AFna0=", + "dependencies": [ + "const", + "either", + "newtype", + "prelude", + "tuples" + ] + }, + "catenable-lists": { + "type": "registry", + "version": "7.0.0", + "integrity": "sha256-7+i/MHBLIRh604iCNT4ENWRWE/wuHIotER4kpdX9Ve0=", + "dependencies": [ + "control", + "foldable-traversable", + "lists", + "maybe", + "prelude", + "tuples", + "unfoldable" + ] + }, + "console": { + "type": "registry", + "version": "6.1.0", + "integrity": "sha256-3T5PPz1mATZmV0C4GzkCkpLlCa5xG7u8ZNgnLrrrI1Q=", + "dependencies": [ + "effect", + "prelude" + ] + }, + "const": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-S+m0lQsxnji0z1XRUmkn+3RFuWJ5CXWuIr1u3i8Bfoc=", + "dependencies": [ + "invariant", + "newtype", + "prelude" + ] + }, + "contravariant": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-nuckEWqL80NaPmR/l9AUyrfycNh18XcvlZV9PAamwqc=", + "dependencies": [ + "const", + "either", + "newtype", + "prelude", + "tuples" + ] + }, + "control": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-0vxyYh5FL+ilxgLo954w1LqCUC0RSIivNNlb9CaNUQg=", + "dependencies": [ + "newtype", + "prelude" + ] + }, + "datetime": { + "type": "registry", + "version": "6.1.0", + "integrity": "sha256-tbv6eDXy6QOD7YSknxYSbsDF32OC2JrNbSBpzMs7Doc=", + "dependencies": [ + "bifunctors", + "control", + "either", + "enums", + "foldable-traversable", + "functions", + "gen", + "integers", + "lists", + "maybe", + "newtype", + "numbers", + "ordered-collections", + "partial", + "prelude", + "tuples" + ] + }, + "distributive": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-netyJK4B32PDYHD0tF2AenKgo3urzbI770ycM0pArAo=", + "dependencies": [ + "identity", + "newtype", + "prelude", + "tuples", + "type-equality" + ] + }, + "effect": { + "type": "registry", + "version": "4.0.0", + "integrity": "sha256-DdqU3bncRTjgMVPPRlAuGHVeajSPEcRaRhNuio7if6s=", + "dependencies": [ + "prelude" + ] + }, + "either": { + "type": "registry", + "version": "6.1.0", + "integrity": "sha256-tBHx3PgtH4GZOApZCDkcM7szRTYJinrUrVGWazQCUUg=", + "dependencies": [ + "control", + "invariant", + "maybe", + "prelude" + ] + }, + "enums": { + "type": "registry", + "version": "6.0.1", + "integrity": "sha256-sdZOmLX5+5pASGpvVyT0vSD5BBYQjZiayjV5XiPutso=", + "dependencies": [ + "control", + "either", + "gen", + "maybe", + "newtype", + "nonempty", + "partial", + "prelude", + "tuples", + "unfoldable" + ] + }, + "exceptions": { + "type": "registry", + "version": "6.1.0", + "integrity": "sha256-nRrr+N0wk0TUFOWLR7e1n1oxcXo/X345bQUtoY9lW6A=", + "dependencies": [ + "effect", + "either", + "maybe", + "prelude" + ] + }, + "exists": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-vtLbrWNaI+pzx/2fw2AQnCovoLtcosClIhjO26QKkh8=", + "dependencies": [ + "unsafe-coerce" + ] + }, + "exitcodes": { + "type": "registry", + "version": "4.0.0", + "integrity": "sha256-xBl4aFSEQ05Owp1ZvO6OxxvLK3LVzU35RSbj79SsePQ=", + "dependencies": [ + "enums", + "maybe", + "prelude" + ] + }, + "foldable-traversable": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-NGGWyCio/xjce6fPP7y3wwg7CheqllID6aJudDxbWhA=", + "dependencies": [ + "bifunctors", + "const", + "control", + "either", + "functors", + "identity", + "maybe", + "newtype", + "orders", + "prelude", + "tuples" + ] + }, + "foreign": { + "type": "registry", + "version": "7.0.0", + "integrity": "sha256-jiDRMVQfovGsbbA/FzbzYf6iWk9i2b5gNrIjz+gFfsI=", + "dependencies": [ + "either", + "functions", + "integers", + "lists", + "maybe", + "prelude", + "strings", + "transformers", + "unsafe-coerce" + ] + }, + "foreign-object": { + "type": "registry", + "version": "4.1.0", + "integrity": "sha256-x/Q7r80z/vmHRKvPwhYmHP/DnJciPtsyGfRTMzayKIU=", + "dependencies": [ + "arrays", + "foldable-traversable", + "functions", + "gen", + "lists", + "maybe", + "prelude", + "st", + "tailrec", + "tuples", + "typelevel-prelude", + "unfoldable", + "unsafe-coerce" + ] + }, + "fork": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-0keBVeZZg1eCZEy/En1CohVW829gQUqKtqBNIRa93/A=", + "dependencies": [ + "aff", + "prelude", + "transformers" + ] + }, + "free": { + "type": "registry", + "version": "7.1.0", + "integrity": "sha256-tUBInfUpRQEw4u94GWcYW7EYdmSdDHSRn88a+C0eltU=", + "dependencies": [ + "catenable-lists", + "control", + "distributive", + "either", + "exists", + "foldable-traversable", + "invariant", + "lazy", + "maybe", + "prelude", + "tailrec", + "transformers", + "tuples", + "unsafe-coerce" + ] + }, + "functions": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-0jgtOr+SFO4UScKc40oA/9Vdcf2rLn3h3vZlY0KfqVo=", + "dependencies": [ + "prelude" + ] + }, + "functors": { + "type": "registry", + "version": "5.0.0", + "integrity": "sha256-W1o/4wcp6S3chodYL8uixlXK2mfr1L+SzM1R+whqUco=", + "dependencies": [ + "bifunctors", + "const", + "contravariant", + "control", + "distributive", + "either", + "invariant", + "maybe", + "newtype", + "prelude", + "profunctor", + "tuples", + "unsafe-coerce" + ] + }, + "gen": { + "type": "registry", + "version": "4.0.0", + "integrity": "sha256-kyOateeOtQa07vfTMYeSuCKdelgKE1R65fwKkZ10wsY=", + "dependencies": [ + "either", + "foldable-traversable", + "identity", + "maybe", + "newtype", + "nonempty", + "prelude", + "tailrec", + "tuples", + "unfoldable" + ] + }, + "identity": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-RY/iXPpxpqvKHYfJeFVNI1J06kohB9rbtWYuha8t0LE=", + "dependencies": [ + "control", + "invariant", + "newtype", + "prelude" + ] + }, + "indexed-monad": { + "type": "registry", + "version": "3.0.0", + "integrity": "sha256-84PslUkPKyrFUGeq981auE+zODsQO/g8rnqwgcN0zQM=", + "dependencies": [ + "newtype", + "prelude" + ] + }, + "integers": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-Y8yozC1uHRLcruobEyv5/bMKzE1BoKJ/olHv6o+bgm8=", + "dependencies": [ + "maybe", + "numbers", + "prelude" + ] + }, + "invariant": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-HyoT1I5qIHRq8RSZji6zZDvqnpVjLw748utrKwZtqsw=", + "dependencies": [ + "control", + "prelude" + ] + }, + "js-date": { + "type": "registry", + "version": "8.0.0", + "integrity": "sha256-DNQrp4xYc8o80jtxo0aOkUeXGi6h0Xidkk2ZQ8Y4l5Y=", + "dependencies": [ + "datetime", + "effect", + "enums", + "foreign", + "functions", + "integers", + "maybe", + "prelude" + ] + }, + "lazy": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-MHRC+1Pc+AjortBp4b/e1e6KpEpsDwaJBNBB7TOL+1I=", + "dependencies": [ + "control", + "foldable-traversable", + "invariant", + "prelude" + ] + }, + "lists": { + "type": "registry", + "version": "7.0.0", + "integrity": "sha256-/mGd7wLoU+wsTcqii7SSUByxsvwvjnu2PjwAD47yYb4=", + "dependencies": [ + "bifunctors", + "control", + "foldable-traversable", + "lazy", + "maybe", + "newtype", + "nonempty", + "partial", + "prelude", + "tailrec", + "tuples", + "unfoldable" + ] + }, + "maybe": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-8X6XEgtZ5lqfkEuc1hWOofnL6mwhk8gSJTxwvbR/SbY=", + "dependencies": [ + "control", + "invariant", + "newtype", + "prelude" + ] + }, + "media-types": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-3Wyq+vfqJFTmy1k6DGVnXStxtZxgK631wusDPzlFVxg=", + "dependencies": [ + "newtype", + "prelude" + ] + }, + "mmorph": { + "type": "registry", + "version": "7.0.0", + "integrity": "sha256-Cfltaq+tfYjuSoSBN/b8cSQZbvZTqIRs6ebQewbIkGs=", + "dependencies": [ + "bifunctors", + "either", + "free", + "functors", + "identity", + "maybe", + "newtype", + "prelude", + "transformers", + "tuples" + ] + }, + "newtype": { + "type": "registry", + "version": "5.0.0", + "integrity": "sha256-dt6w0cty4OS+Pjt9fsh3iU6ottqSU83mdAZkaEEvo6c=", + "dependencies": [ + "prelude", + "safe-coerce" + ] + }, + "node-buffer": { + "type": "registry", + "version": "9.0.0", + "integrity": "sha256-RdQjilmEHqsT4fwpCr8Mavw8KTafYrS3ZM6zeAAVAl8=", + "dependencies": [ + "arraybuffer-types", + "effect", + "functions", + "maybe", + "nullable", + "partial", + "prelude", + "st", + "unsafe-coerce" + ] + }, + "node-event-emitter": { + "type": "registry", + "version": "3.0.0", + "integrity": "sha256-wodx71NxJBPXOaawFn01V1ByYB2vT+I3RuV2giOVKMg=", + "dependencies": [ + "effect", + "either", + "functions", + "maybe", + "nullable", + "prelude", + "unsafe-coerce" + ] + }, + "node-fs": { + "type": "registry", + "version": "9.2.0", + "integrity": "sha256-fxioTSm9y47WuYs9F/7nxCh/RVDCl3Kr3Hg779J4SJA=", + "dependencies": [ + "aff", + "datetime", + "effect", + "either", + "enums", + "exceptions", + "functions", + "integers", + "js-date", + "maybe", + "node-buffer", + "node-path", + "node-streams", + "nullable", + "partial", + "prelude", + "strings" + ] + }, + "node-path": { + "type": "registry", + "version": "5.0.1", + "integrity": "sha256-j7n/SmpVz0FOMJl4XZop3ofJ+MeIPkMNqUEUKHEL6Us=", + "dependencies": [ + "effect" + ] + }, + "node-process": { + "type": "registry", + "version": "11.2.0", + "integrity": "sha256-onzKeNmaeYfN3HSDPqSFTrrP2Yl9tnVsfKKhnf2plxM=", + "dependencies": [ + "effect", + "exceptions", + "foreign", + "foreign-object", + "maybe", + "node-event-emitter", + "node-streams", + "nullable", + "posix-types", + "prelude", + "strings" + ] + }, + "node-streams": { + "type": "registry", + "version": "9.0.1", + "integrity": "sha256-yuVGm/R/tBr4Nphi+a1a984Z0fkmN9Q5wWtSmbmJTpA=", + "dependencies": [ + "aff", + "arrays", + "effect", + "either", + "exceptions", + "maybe", + "node-buffer", + "node-event-emitter", + "nullable", + "prelude", + "refs", + "st", + "tailrec", + "unsafe-coerce" + ] + }, + "nonempty": { + "type": "registry", + "version": "7.0.0", + "integrity": "sha256-Ctkq8/+KiGqCE53Y/LvibA/coy7ev9HtRZU+GYS7yfQ=", + "dependencies": [ + "control", + "foldable-traversable", + "maybe", + "prelude", + "tuples", + "unfoldable" + ] + }, + "now": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-mTyG4s8tps3XIf0jjV/lME2/QlwMzrQly2wqfSSUM3o=", + "dependencies": [ + "datetime", + "effect", + "prelude" + ] + }, + "nullable": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-CDAZk+L9Sc0GCFTkE8n+qdp4Ys8avvnkU+m2hVALt7M=", + "dependencies": [ + "functions", + "maybe", + "prelude" + ] + }, + "numbers": { + "type": "registry", + "version": "9.0.1", + "integrity": "sha256-ZydYckgwRAnRaFC7pu6fADhzdwX+UqHZrfJyet64zls=", + "dependencies": [ + "functions", + "maybe", + "prelude" + ] + }, + "open-memoize": { + "type": "registry", + "version": "6.2.0", + "integrity": "sha256-yJLuVYX8FocHIJ+6q7efH/Pj4S+e1Y57DZ5Dn7qf4ww=", + "dependencies": [ + "either", + "integers", + "lazy", + "lists", + "maybe", + "partial", + "prelude", + "strings", + "tuples" + ] + }, + "optparse": { + "type": "registry", + "version": "5.0.1", + "integrity": "sha256-2btDjHPRR0uujUQJuZAN9AzvVoXe7yG6IwnY5evERhQ=", + "dependencies": [ + "arrays", + "bifunctors", + "control", + "effect", + "either", + "enums", + "exists", + "exitcodes", + "foldable-traversable", + "free", + "integers", + "lazy", + "lists", + "maybe", + "newtype", + "node-buffer", + "node-process", + "node-streams", + "nonempty", + "numbers", + "open-memoize", + "partial", + "prelude", + "strings", + "tailrec", + "transformers", + "tuples" + ] + }, + "ordered-collections": { + "type": "registry", + "version": "3.2.0", + "integrity": "sha256-NaEXc2cz/7lJfxPWEja4XlZbGxuRqJwFKQJjsJf51kQ=", + "dependencies": [ + "arrays", + "control", + "foldable-traversable", + "functions", + "gen", + "lists", + "maybe", + "newtype", + "partial", + "prelude", + "safe-coerce", + "tailrec", + "tuples", + "unfoldable" + ] + }, + "orders": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-nSMxZK7wxyDULkjZqvMyB71mVo6b0AyLLHosDVbv1XM=", + "dependencies": [ + "newtype", + "prelude" + ] + }, + "parallel": { + "type": "registry", + "version": "7.0.0", + "integrity": "sha256-bAGpVhrFz2IyHkA4MR7+tE/19FZ7dzYBdYPgK5svkqw=", + "dependencies": [ + "control", + "effect", + "either", + "foldable-traversable", + "functors", + "maybe", + "newtype", + "prelude", + "profunctor", + "refs", + "transformers" + ] + }, + "partial": { + "type": "registry", + "version": "4.0.0", + "integrity": "sha256-mdrlJBAgFMh79hNRW39uv7c+BwnnaOrAMmdh7+VhEhs=", + "dependencies": [] + }, + "pipes": { + "type": "registry", + "version": "8.0.0", + "integrity": "sha256-dtUNpG8BGVr7pu6mQZyAnUAftUHgNS7f0QH3Kw5UTpQ=", + "dependencies": [ + "aff", + "control", + "effect", + "either", + "foldable-traversable", + "identity", + "lists", + "maybe", + "mmorph", + "newtype", + "prelude", + "tailrec", + "transformers", + "tuples" + ] + }, + "posix-types": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-Je5jG439F/SFO/IvVevZnWVxDIonrehlKuJkefP2lHE=", + "dependencies": [ + "maybe", + "newtype", + "prelude" + ] + }, + "prelude": { + "type": "registry", + "version": "6.0.2", + "integrity": "sha256-IqykrDRquGUD/LRSad7y75hZv3bUsGQ4knc8tdez8Qw=", + "dependencies": [] + }, + "profunctor": { + "type": "registry", + "version": "6.0.1", + "integrity": "sha256-Ow0mJC+PIIRq/a3mzCWY5vxuTgR/e+Ee68+mWeSRnWY=", + "dependencies": [ + "control", + "distributive", + "either", + "exists", + "invariant", + "newtype", + "prelude", + "tuples" + ] + }, + "profunctor-lenses": { + "type": "registry", + "version": "8.0.0", + "integrity": "sha256-mVIYR3kEMHyO2m+VicJeZeVyDJ4IgvkMzDll3JdnRN4=", + "dependencies": [ + "arrays", + "bifunctors", + "const", + "control", + "distributive", + "either", + "foldable-traversable", + "foreign-object", + "functors", + "identity", + "lists", + "maybe", + "newtype", + "ordered-collections", + "partial", + "prelude", + "profunctor", + "record", + "safe-coerce", + "transformers", + "tuples" + ] + }, + "react-basic": { + "type": "registry", + "version": "17.0.0", + "integrity": "sha256-RZA6jqfbrFHLXYD1ARlnfHp2YkT9IjUTkUwsk7Rqn8s=", + "dependencies": [ + "effect", + "prelude", + "record" + ] + }, + "react-basic-dom": { + "type": "registry", + "version": "7.0.0", + "integrity": "sha256-q5WQnD1cEVe/hzWDziZfPM9DclgCUBowRgbBg1xReSA=", + "dependencies": [ + "arrays", + "effect", + "foldable-traversable", + "foreign-object", + "maybe", + "nullable", + "prelude", + "react-basic", + "record", + "unsafe-coerce", + "web-dom", + "web-events", + "web-file", + "web-html" + ] + }, + "react-basic-hooks": { + "type": "registry", + "version": "9.1.1", + "integrity": "sha256-wUZMNNivUj6yJDk3rbgeEgljfv2gq1bPHKHEJbkzyNQ=", + "dependencies": [ + "aff", + "aff-promise", + "bifunctors", + "console", + "control", + "datetime", + "effect", + "either", + "exceptions", + "foldable-traversable", + "foreign-object", + "functions", + "indexed-monad", + "integers", + "maybe", + "newtype", + "now", + "nullable", + "ordered-collections", + "prelude", + "react-basic", + "refs", + "tuples", + "type-equality", + "unsafe-coerce", + "unsafe-reference", + "web-html" + ] + }, + "record": { + "type": "registry", + "version": "4.0.0", + "integrity": "sha256-WQ8fqp4X1wTA70J4qUcPW4Z7DCwx6e5KJnT/EuTdWSc=", + "dependencies": [ + "functions", + "prelude", + "unsafe-coerce" + ] + }, + "refs": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-KKD5G9dR2SauuDGULUJsxjqDOEi1Jqm+2Sq5U2mY8YU=", + "dependencies": [ + "effect", + "prelude" + ] + }, + "safe-coerce": { + "type": "registry", + "version": "2.0.0", + "integrity": "sha256-EJrxtKt5xC7TYjBZrSBO/J7Aw3DmtilYjt4olpAXWVc=", + "dependencies": [ + "unsafe-coerce" + ] + }, + "spec": { + "type": "registry", + "version": "8.1.2", + "integrity": "sha256-klPPJ6lBQI1CGOAdLJ+ZoGRt8XZippkTKjn53BrSkL0=", + "dependencies": [ + "aff", + "ansi", + "arrays", + "avar", + "bifunctors", + "control", + "datetime", + "effect", + "either", + "exceptions", + "foldable-traversable", + "fork", + "identity", + "integers", + "lists", + "maybe", + "newtype", + "now", + "ordered-collections", + "parallel", + "pipes", + "prelude", + "refs", + "strings", + "tailrec", + "transformers", + "tuples" + ] + }, + "spec-node": { + "type": "registry", + "version": "0.0.3", + "integrity": "sha256-8/9+g0obbamV0YtqzmttbWs8HaWF7CEeW+eDtqzuAAo=", + "dependencies": [ + "aff", + "argonaut-codecs", + "argonaut-core", + "arrays", + "control", + "datetime", + "effect", + "either", + "foldable-traversable", + "identity", + "integers", + "maybe", + "newtype", + "node-buffer", + "node-fs", + "node-process", + "now", + "numbers", + "optparse", + "ordered-collections", + "partial", + "prelude", + "spec", + "strings", + "tuples" + ] + }, + "st": { + "type": "registry", + "version": "6.2.0", + "integrity": "sha256-WI4MEkkwUd4pnwZQ3G8VKWgX5t1RSNJludm5e9boaRo=", + "dependencies": [ + "effect", + "partial", + "prelude", + "tailrec", + "unsafe-coerce" + ] + }, + "strings": { + "type": "registry", + "version": "6.0.1", + "integrity": "sha256-FNto2hoNW5Da6W6crIk77YXMagBvOGHZE1kO7eZ1vLM=", + "dependencies": [ + "arrays", + "control", + "either", + "enums", + "foldable-traversable", + "gen", + "integers", + "maybe", + "newtype", + "nonempty", + "partial", + "prelude", + "tailrec", + "tuples", + "unfoldable", + "unsafe-coerce" + ] + }, + "tailrec": { + "type": "registry", + "version": "6.1.0", + "integrity": "sha256-xrorCfP0xV1wubs27idQCHQqdvSUuqmmL/am7Ji1wVU=", + "dependencies": [ + "bifunctors", + "effect", + "either", + "identity", + "maybe", + "partial", + "prelude", + "refs" + ] + }, + "transformers": { + "type": "registry", + "version": "6.1.0", + "integrity": "sha256-QJmgNT/y7ljPHSsXaW4zxF/982BFiQ90KNL1g/NtEOQ=", + "dependencies": [ + "control", + "distributive", + "effect", + "either", + "exceptions", + "foldable-traversable", + "identity", + "lazy", + "maybe", + "newtype", + "prelude", + "st", + "tailrec", + "tuples", + "unfoldable" + ] + }, + "tuples": { + "type": "registry", + "version": "7.0.0", + "integrity": "sha256-BKy7EfK8S1KeTCwyWqyW1wwcpSAQuh3IsczSVgS6fzY=", + "dependencies": [ + "control", + "invariant", + "prelude" + ] + }, + "type-equality": { + "type": "registry", + "version": "4.0.1", + "integrity": "sha256-BBqYOSnAKmayRvR5mtZoCf4SlYs2ipatD/+5nQx73aw=", + "dependencies": [] + }, + "typelevel-prelude": { + "type": "registry", + "version": "7.0.0", + "integrity": "sha256-+pHi14/40mTj/+lmCWqL0T7iXIXD1+NSg/KItyyoB0A=", + "dependencies": [ + "prelude", + "type-equality" + ] + }, + "unfoldable": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-BK/6By1sKp/ztk+9CF3q43SV0QDTLVdsGqFerKHSmbg=", + "dependencies": [ + "foldable-traversable", + "maybe", + "partial", + "prelude", + "tuples" + ] + }, + "unsafe-coerce": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-0L1QsaY20OILjfU5TV72d3U/tSjhmL9hJ32WMp857Lk=", + "dependencies": [] + }, + "unsafe-reference": { + "type": "registry", + "version": "5.0.0", + "integrity": "sha256-ttSJTQUnK8AK2eGOsfRxLUJEDPL6pnmExjbiOqfwC6I=", + "dependencies": [ + "prelude" + ] + }, + "web-dom": { + "type": "registry", + "version": "6.0.0", + "integrity": "sha256-rVeqkxChkjqisDvOujy9BMEgGqJkwX3t6g21bXfiG5o=", + "dependencies": [ + "effect", + "enums", + "maybe", + "newtype", + "nullable", + "prelude", + "unsafe-coerce", + "web-events" + ] + }, + "web-events": { + "type": "registry", + "version": "4.0.0", + "integrity": "sha256-wZNeldG0OU+8qGycUJ9e6vxf1/GC4Ep4OlRMhvjs9LA=", + "dependencies": [ + "datetime", + "effect", + "enums", + "foreign", + "functions", + "maybe", + "newtype", + "nullable", + "prelude", + "unsafe-coerce" + ] + }, + "web-file": { + "type": "registry", + "version": "4.0.0", + "integrity": "sha256-txsdkeWBKU/+5v9m5c6kysgJQSDyV1r7MHaeT4STpjQ=", + "dependencies": [ + "datetime", + "effect", + "enums", + "foreign", + "integers", + "maybe", + "media-types", + "nullable", + "numbers", + "partial", + "prelude", + "tuples", + "unfoldable", + "unsafe-coerce", + "web-events" + ] + }, + "web-html": { + "type": "registry", + "version": "4.1.1", + "integrity": "sha256-yOuZJGUxFrivHKpo/jKuKzFZaq6PPPE64ftSysXFssk=", + "dependencies": [ + "effect", + "enums", + "foreign", + "functions", + "js-date", + "maybe", + "media-types", + "newtype", + "nullable", + "prelude", + "unsafe-coerce", + "web-dom", + "web-events", + "web-file", + "web-storage" + ] + }, + "web-storage": { + "type": "registry", + "version": "5.0.0", + "integrity": "sha256-YJfos55oeKtBStNfoWfeflSy8j+4IDym5eaZtIY7YM4=", + "dependencies": [ + "effect", + "maybe", + "nullable", + "prelude", + "unsafe-coerce", + "web-events" + ] + } + } +} diff --git a/spago.test.dhall b/spago.test.dhall deleted file mode 100644 index 2272207..0000000 --- a/spago.test.dhall +++ /dev/null @@ -1,10 +0,0 @@ -let conf = ./spago.dhall - -let dependencies = [ "spec" ] - -let sources = [ "test/**/*.purs" ] - -in conf // - { dependencies = conf.dependencies # dependencies - , sources = conf.sources # sources - } diff --git a/spago.yaml b/spago.yaml new file mode 100644 index 0000000..f9139a9 --- /dev/null +++ b/spago.yaml @@ -0,0 +1,38 @@ +package: + name: react-halo + publish: + version: 4.0.0 + license: BSD-3-Clause + location: + githubOwner: robertdp + githubRepo: purescript-react-halo + dependencies: + - aff + - avar + - effect + - either + - exceptions + - foldable-traversable + - maybe + - newtype + - ordered-collections + - parallel + - prelude + - profunctor-lenses + - react-basic-hooks + - refs + - transformers + - tuples + - unsafe-reference + test: + main: Test.Main + dependencies: + - console + - control + - exceptions + - react-basic-dom + - spec + - spec-node +workspace: + packageSet: + registry: 80.8.0 diff --git a/src/React/Halo.purs b/src/React/Halo.purs index c33e2c6..26098f7 100644 --- a/src/React/Halo.purs +++ b/src/React/Halo.purs @@ -1,9 +1,19 @@ +-- | Component-scoped action handling for PureScript React. +-- | +-- | A Halo component keeps application effects in a caller-defined monad `m`. +-- | `component` or `useHalo` receives a natural transformation from `m` to +-- | `Aff`, while `HaloM` adds component props, state, actions, cancellable +-- | forks, synchronous cleanup, subscriptions, and lifecycle ownership. +-- | +-- | Import this module for the intentional public API. Runtime constructors and +-- | ownership records remain internal. module React.Halo ( module Exports ) where import React.Halo.Component (ComponentSpec, component) as Exports -import React.Halo.Hook (HookSpec, UseHalo(..), useHalo) as Exports -import React.Halo.Internal.Control (HaloAp, HaloM, fork, hoist, hoistAp, kill, props, subscribe, subscribe', unsubscribe) as Exports -import React.Halo.Internal.Eval (EvalSpec, defaultEval, mkEval) as Exports -import React.Halo.Internal.Types (ForkId, Lifecycle(..), SubscriptionId) as Exports +import React.Halo.Handlers (Handlers, defaultHandlers) as Exports +import React.Halo.Hook (HaloResult, HookSpec, UseHalo, useHalo) as Exports +import React.Halo.Internal.Runtime (HaloAp, HaloM, fork, getProps, kill, registerCleanup, releaseCleanup, subscribe, subscribeWithId, unsubscribe) as Exports +import React.Halo.Internal.Types (CleanupId, ErrorContext(..), ForkId, SubscriptionId) as Exports +import React.Halo.Subscription (Emitter, makeEmitter) as Exports diff --git a/src/React/Halo/Component.purs b/src/React/Halo/Component.purs index 6991772..fe519c9 100644 --- a/src/React/Halo/Component.purs +++ b/src/React/Halo/Component.purs @@ -1,26 +1,61 @@ -module React.Halo.Component where +module React.Halo.Component + ( ComponentSpec + , component + ) where import Prelude -import Data.Tuple.Nested ((/\)) import Effect (Effect) -import Effect.Aff (Aff) +import Effect.Aff (Aff, Error) import React.Basic.Hooks (Component, JSX) import React.Basic.Hooks as React +import React.Halo.Handlers (Handlers) import React.Halo.Hook (useHalo) -import React.Halo.Internal.Control (HaloM) -import React.Halo.Internal.Types (Lifecycle) +import React.Halo.Internal.Task.Types (View) +import React.Halo.Internal.Types (ErrorContext) +-- | Configuration for a complete Halo-owned React component. +-- | +-- | `initialState` receives the initial props once per mount. Later prop changes +-- | start `handlers.onPropsChange` and do not recreate state. The renderer +-- | receives current props plus one coherent state/task-view snapshot and +-- | synchronous action dispatch. type ComponentSpec props state action m = - { initialState :: props -> state - , eval :: Lifecycle props action -> HaloM props state action m Unit - , render :: { props :: props, state :: state, send :: action -> Effect Unit } -> JSX + { handlers :: Handlers props state action m + , initialState :: props -> state + , onError :: ErrorContext props action -> Error -> Effect Unit + , render :: + { dispatch :: action -> Effect Unit + , props :: props + , state :: state + , tasks :: View state + } + -> JSX } --- | Build a component by providing a name and a Halo component spec. -component :: forall props state action. String -> ComponentSpec props state action Aff -> Component props -component name spec@{ eval, render } = +-- | Build a complete React component around a Halo action runtime. +-- | +-- | The natural transformation is the application boundary: it translates `m` +-- | into the component-owned `Aff` roots managed by Halo. It must return the +-- | computation that performs the work rather than detach it. +component + :: forall props state action m + . String + -> (m ~> Aff) + -> ComponentSpec props state action m + -> Component props +component name runInAff spec = React.component name \props -> React.do initialState <- React.useMemo unit \_ -> spec.initialState props - state /\ send <- useHalo { props, initialState, eval } - pure (render { props, state, send }) + halo <- useHalo runInAff + { handlers: spec.handlers + , initialState + , onError: spec.onError + , props + } + pure $ spec.render + { dispatch: halo.dispatch + , props + , state: halo.state + , tasks: halo.tasks + } diff --git a/src/React/Halo/Handlers.purs b/src/React/Halo/Handlers.purs new file mode 100644 index 0000000..d7a207f --- /dev/null +++ b/src/React/Halo/Handlers.purs @@ -0,0 +1,30 @@ +module React.Halo.Handlers + ( Handlers + , defaultHandlers + ) where + +import Prelude + +import React.Halo.Internal.Runtime (Handlers) as Runtime + +-- | Activation, prop-change, and action callbacks for a Halo component. +-- | +-- | Each invocation is an independent root owned by the current React +-- | activation. `onActivate` is repeatable under StrictMode, not an exactly-once +-- | mount callback. `onPropsChange` receives the previous props; use +-- | `React.Halo.getProps` to read current props. `onAction` starts for every +-- | dispatched action, so action handlers can overlap. +-- | +-- | There is no asynchronous deactivation callback because React cleanup is +-- | synchronous. Use Aff finalizers for forked processes and emitter cleanup +-- | for subscriptions. +type Handlers props state action m = Runtime.Handlers props state action m + +-- | Handlers that do nothing. Use a record update to configure only the +-- | callbacks a component needs. +defaultHandlers :: forall props state action m. Handlers props state action m +defaultHandlers = + { onActivate: pure unit + , onPropsChange: \_ -> pure unit + , onAction: \_ -> pure unit + } diff --git a/src/React/Halo/Hook.purs b/src/React/Halo/Hook.purs index ebce21c..dadcf94 100644 --- a/src/React/Halo/Hook.purs +++ b/src/React/Halo/Hook.purs @@ -1,36 +1,103 @@ -module React.Halo.Hook where +module React.Halo.Hook + ( HaloResult + , HookSpec + , UseHalo(..) + , useHalo + ) where import Prelude + import Data.Newtype (class Newtype) -import Data.Tuple.Nested (type (/\), (/\)) +import Data.Tuple.Nested ((/\)) import Effect (Effect) -import Effect.Aff (Aff) +import Effect.Aff (Aff, Error) import Effect.Unsafe (unsafePerformEffect) import React.Basic.Hooks (Hook, UseEffect, UseMemo, UseState) import React.Basic.Hooks as React -import React.Halo.Internal.Control (HaloM) -import React.Halo.Internal.Eval (handleAction, handleUpdate, runFinalize, runInitialize) -import React.Halo.Internal.State (HaloState, createInitialState) -import React.Halo.Internal.Types (Lifecycle) +import React.Halo.Handlers (Handlers) +import React.Halo.Internal.Runtime (Runtime, activate, createRuntime, deactivate, dispatch, syncSpec, updateProps) +import React.Halo.Internal.Task.Types (View) +import React.Halo.Internal.Task.Types as Task +import React.Halo.Internal.Types (ErrorContext) +-- | Configuration for `useHalo`. +-- | +-- | `initialState` initializes the hook once. Later `props` changes start +-- | `handlers.onPropsChange` without recreating state. New roots use the latest +-- | handlers, error callback, state setter, and application interpreter supplied +-- | by a render. type HookSpec props state action m = - { props :: props + { handlers :: Handlers props state action m , initialState :: state - , eval :: Lifecycle props action -> HaloM props state action m Unit + , onError :: ErrorContext props action -> Error -> Effect Unit + , props :: props + } + +-- | Coherent component state, immutable task-authority view, and synchronous +-- | action dispatch exposed to rendering code. Dispatch starts an independent +-- | handler root while the current React activation is active. +type HaloResult state action = + { dispatch :: action -> Effect Unit + , state :: state + , tasks :: View state } -newtype UseHalo props state action hooks = UseHalo (UseEffect Unit (UseEffect Unit (UseMemo Unit (HaloState props state action) (UseState state hooks)))) +newtype UseHalo props state action m hooks = UseHalo + ( UseEffect Unit + ( UseEffect Unit + ( UseEffect Unit + ( UseMemo Unit (Runtime props state action m) + (UseState { state :: state, tasks :: View state } hooks) + ) + ) + ) + ) -derive instance newtypeUseHalo :: Newtype (UseHalo props state action hooks) _ +derive instance newtypeUseHalo :: Newtype (UseHalo props state action m hooks) _ --- | Run renderless Halo in the current component. This allows Halo to be used with other hooks and other ways of --- | building components. -useHalo :: forall props state action. HookSpec props state action Aff -> Hook (UseHalo props state action) (state /\ (action -> Effect Unit)) -useHalo { props, initialState, eval } = +-- | Run Halo inside a `react-basic-hooks` component. +-- | +-- | The natural transformation interprets application effects in `m` inside +-- | `Aff` roots owned by the active React scope. It must return the computation +-- | that performs the work rather than detach it. New handlers use the latest +-- | interpreter; existing roots retain their snapshot, and a fork inherits the +-- | snapshot of the root that launches it. +-- | +-- | Effect cleanup fences the activation, normalizes managed task state, runs +-- | synchronous cleanup, and requests cancellation of every handler and fork. +-- | A StrictMode setup replay publishes normalized state before new work. +useHalo + :: forall props state action m + . (m ~> Aff) + -> HookSpec props state action m + -> Hook (UseHalo props state action m) (HaloResult state action) +useHalo runInAff { props, initialState, handlers, onError } = React.coerceHook React.do - state /\ setState <- React.useState' initialState - halo <- React.useMemo unit \_ -> unsafePerformEffect $ - createInitialState { props, state: initialState, eval, update: setState } - React.useEffectOnce (runInitialize halo *> pure (runFinalize halo)) - React.useEffectAlways (handleUpdate halo props *> mempty) - pure (state /\ handleAction halo) + snapshot /\ setSnapshot <- React.useState' + { state: initialState + , tasks: Task.emptyView initialState + } + runtime <- React.useMemo unit \_ -> unsafePerformEffect $ + createRuntime runInAff + { initialProps: props + , initialState + , spec: { handlers, onError } + , stateUpdate: \state tasks -> setSnapshot { state, tasks } + } + React.useEffectAlways do + syncSpec runtime runInAff + { spec: { handlers, onError } + , stateUpdate: \state tasks -> setSnapshot { state, tasks } + } + pure mempty + React.useEffectOnce do + activate runtime + pure (deactivate runtime) + React.useEffectAlways do + updateProps runtime props + pure mempty + pure + { dispatch: dispatch runtime + , state: snapshot.state + , tasks: snapshot.tasks + } diff --git a/src/React/Halo/Internal/Control.purs b/src/React/Halo/Internal/Control.purs deleted file mode 100644 index 6627fde..0000000 --- a/src/React/Halo/Internal/Control.purs +++ /dev/null @@ -1,167 +0,0 @@ -module React.Halo.Internal.Control where - -import Prelude -import Control.Applicative.Free (FreeAp, hoistFreeAp, liftFreeAp) -import Control.Monad.Error.Class (class MonadThrow, throwError) -import Control.Monad.Free (Free, hoistFree, liftF) -import Control.Monad.Reader (class MonadAsk, ask) -import Control.Monad.Rec.Class (class MonadRec, Step(..), tailRecM) -import Control.Monad.State (class MonadState) -import Control.Monad.Trans.Class (class MonadTrans, lift) -import Control.Monad.Writer (class MonadTell, tell) -import Control.Parallel (class Parallel) -import Data.Bifunctor (lmap) -import Data.Tuple (Tuple) -import Effect.Aff.Class (class MonadAff, liftAff) -import Effect.Class (class MonadEffect, liftEffect) -import Halogen.Subscription (Emitter) -import React.Halo.Internal.Types (ForkId, SubscriptionId) - --- | The Halo evaluation algebra --- | --- | - `props` are the component props --- | - `state` is the component state --- | - `action` is the set of actions that the component handles --- | - `m` is the monad used during evaluation --- | - `a` is the result type -data HaloF props state action (m :: Type -> Type) a - = Props (props -> a) - | State (state -> Tuple a state) - | Subscribe (SubscriptionId -> Emitter action) (SubscriptionId -> a) - | Unsubscribe SubscriptionId a - | Lift (m a) - | Par (HaloAp props state action m a) - | Fork (HaloM props state action m Unit) (ForkId -> a) - | Kill ForkId a - -instance functorHaloF :: Functor m => Functor (HaloF props state action m) where - map f = case _ of - Props k -> Props (f <<< k) - State k -> State (lmap f <<< k) - Subscribe fes k -> Subscribe fes (map f k) - Unsubscribe sid a -> Unsubscribe sid (f a) - Lift m -> Lift (map f m) - Par par -> Par (map f par) - Fork m k -> Fork m (map f k) - Kill fid a -> Kill fid (f a) - --- | The Halo evaluation monad. It lifts the `HaloF` algebra into a free monad. --- | --- | - `props` are the component props --- | - `state` is the component state --- | - `action` is the set of actions that the component handles --- | - `m` is the monad used during evaluation --- | - `a` is the result type -newtype HaloM props state action (m :: Type -> Type) a = HaloM (Free (HaloF props state action m) a) - -derive newtype instance functorHaloM :: Functor (HaloM props state action m) - -derive newtype instance applyHaloM :: Apply (HaloM props state action m) - -derive newtype instance applicativeHaloM :: Applicative (HaloM props state action m) - -derive newtype instance bindHaloM :: Bind (HaloM props state action m) - -derive newtype instance monadHaloM :: Monad (HaloM props state action m) - -derive newtype instance semigroupHaloM :: Semigroup a => Semigroup (HaloM props state action m a) - -derive newtype instance monoidHaloM :: Monoid a => Monoid (HaloM props state action m a) - -instance monadTransHaloM :: MonadTrans (HaloM props state action) where - lift = HaloM <<< liftF <<< Lift - -instance monadEffectHaloM :: MonadEffect m => MonadEffect (HaloM props state action m) where - liftEffect = lift <<< liftEffect - -instance monadAffHaloM :: MonadAff m => MonadAff (HaloM props state action m) where - liftAff = lift <<< liftAff - -instance monadStateHaloM :: MonadState state (HaloM props state action m) where - state = HaloM <<< liftF <<< State - -instance monadRecHaloM :: MonadRec (HaloM props state action m) where - tailRecM k a = - k a - >>= case _ of - Loop x -> tailRecM k x - Done y -> pure y - -instance monadAskHaloM :: MonadAsk r m => MonadAsk r (HaloM props state action m) where - ask = lift ask - -instance monadTellHaloM :: MonadTell w m => MonadTell w (HaloM props state action m) where - tell = lift <<< tell - -instance monadThrowHaloM :: MonadThrow e m => MonadThrow e (HaloM props state action m) where - throwError = lift <<< throwError - --- | The Halo parallel evaluation applicative. It lifts `HaloM` into a free applicative. --- | --- | - `props` are the component props --- | - `state` is the component state --- | - `action` is the set of actions that the component handles --- | - `m` is the monad used during evaluation --- | - `a` is the result type -newtype HaloAp props state action (m :: Type -> Type) a = HaloAp (FreeAp (HaloM props state action m) a) - -derive newtype instance functorHaloAp :: Functor (HaloAp props state action m) - -derive newtype instance applyHaloAp :: Apply (HaloAp props state action m) - -derive newtype instance applicativeHaloAp :: Applicative (HaloAp props state action m) - -instance parallelHaloM :: Parallel (HaloAp props state action m) (HaloM props state action m) where - parallel = HaloAp <<< liftFreeAp - sequential = HaloM <<< liftF <<< Par - --- | Hoist (transform) the base monad of a `HaloM` expression. -hoist :: forall props state action m m'. Functor m => (m ~> m') -> HaloM props state action m ~> HaloM props state action m' -hoist nat (HaloM component) = HaloM (hoistFree go component) - where - go :: HaloF props state action m ~> HaloF props state action m' - go = case _ of - Props k -> Props k - State k -> State k - Subscribe event k -> Subscribe event k - Unsubscribe sid a -> Unsubscribe sid a - Lift m -> Lift (nat m) - Par par -> Par (hoistAp nat par) - Fork m k -> Fork (hoist nat m) k - Kill fid a -> Kill fid a - --- | Hoist (transform) the base applicative of a `HaloAp` expression. -hoistAp :: forall props state action m m'. Functor m => (m ~> m') -> HaloAp props state action m ~> HaloAp props state action m' -hoistAp nat (HaloAp component) = HaloAp (hoistFreeAp (hoist nat) component) - --- | Read the current props. -props :: forall props state action m. HaloM props state action m props -props = HaloM (liftF (Props identity)) - --- | Subscribe to new actions from an `Emitter`. Subscriptions will be automatically cancelled when the component --- | unmounts. --- | --- | Returns a `SubscriptionId` which can be used with `unsubscribe` to manually cancel a subscription. -subscribe :: forall props state action m. Emitter action -> HaloM props state action m SubscriptionId -subscribe = subscribe' <<< const - --- | Same as `subscribe` but the event-producing logic is also passed the `SuscriptionId`. This is useful when events --- | need to unsubscribe themselves. -subscribe' :: forall props state action m. (SubscriptionId -> Emitter action) -> HaloM props state action m SubscriptionId -subscribe' event = HaloM (liftF (Subscribe event identity)) - --- | Cancels the event subscription belonging to the `SubscriptionId`. -unsubscribe :: forall props state action m. SubscriptionId -> HaloM props state action m Unit -unsubscribe sid = HaloM (liftF (Unsubscribe sid unit)) - --- | Start a `HaloM` process running independantly from the current "thread". Forks are tracked automatically and --- | killed when the `Finalize` event occurs (when the component unmounts). New forks can still be created during the --- | `Finalize` event, but once evaluation ends there will be no way of killing them. --- | --- | Returns a `ForkId` for the new process. -fork :: forall props state action m. HaloM props state action m Unit -> HaloM props state action m ForkId -fork m = HaloM (liftF (Fork m identity)) - --- | Kills the process belonging to the `ForkId`. -kill :: forall props state action m. ForkId -> HaloM props state action m Unit -kill fid = HaloM (liftF (Kill fid unit)) diff --git a/src/React/Halo/Internal/Eval.purs b/src/React/Halo/Internal/Eval.purs deleted file mode 100644 index 6258aca..0000000 --- a/src/React/Halo/Internal/Eval.purs +++ /dev/null @@ -1,138 +0,0 @@ -module React.Halo.Internal.Eval where - -import Prelude - -import Control.Applicative.Free (foldFreeAp) -import Control.Monad.Free (foldFree) -import Data.Either (either) -import Data.Foldable (traverse_) -import Data.Map as Map -import Data.Maybe (Maybe(..)) -import Data.Tuple (Tuple(..)) -import Effect (Effect) -import Effect.Aff (Aff, ParAff, finally, parallel, sequential, throwError) -import Effect.Aff as Aff -import Effect.Class (liftEffect) -import Effect.Ref as Ref -import Halogen.Subscription (subscribe, unsubscribe) -import React.Halo.Internal.Control (HaloAp(..), HaloF(..), HaloM(..)) -import React.Halo.Internal.State (HaloState(..)) -import React.Halo.Internal.State as State -import React.Halo.Internal.Types (ForkId(..), Lifecycle(..), SubscriptionId(..)) -import Unsafe.Reference (unsafeRefEq) - --- | Interprets `HaloM` into the base monad `Aff` for asynchronous effects. -evalHaloM :: forall props state action. HaloState props state action -> HaloM props state action Aff ~> Aff -evalHaloM hs (HaloM halo) = foldFree (evalHaloF hs) halo - --- | Interprets `HaloAp` into the base applicative `ParAff` for parallel effects. -evalHaloAp :: forall props state action. HaloState props state action -> HaloAp props state action Aff ~> ParAff -evalHaloAp hs (HaloAp halo) = foldFreeAp (parallel <<< evalHaloM hs) halo - --- | Interprets `HaloF` into the base monad `Aff`, keeping track of state in `HaloState`. -evalHaloF :: forall props state action. HaloState props state action -> HaloF props state action Aff ~> Aff -evalHaloF hs@(HaloState s) = case _ of - Props k -> - liftEffect do - props <- Ref.read s.props - pure (k props) - State f -> - liftEffect do - state <- Ref.read s.state - case f state of - Tuple a state' - | not unsafeRefEq state state' -> do - Ref.write state' s.state - s.update state' - pure a - | otherwise -> pure a - Subscribe sub k -> - liftEffect do - sid <- State.fresh SubscriptionId hs - unlessM (Ref.read s.finalized) do - canceller <- subscribe (sub sid) (handleAction hs) - Ref.modify_ (Map.insert sid canceller) s.subscriptions - pure (k sid) - Unsubscribe sid a -> - liftEffect do - subscription <- Map.lookup sid <$> Ref.read s.subscriptions - traverse_ unsubscribe subscription - pure a - Lift m -> - m - Par p -> - sequential (evalHaloAp hs p) - Fork fh k -> - liftEffect do - fid <- State.fresh ForkId hs - doneRef <- Ref.new false - fiber <- - Aff.launchAff - $ finally - ( liftEffect do - Ref.modify_ (Map.delete fid) s.forks - Ref.write true doneRef - ) - (evalHaloM hs fh) - unlessM (Ref.read doneRef) do - Ref.modify_ (Map.insert fid fiber) s.forks - pure (k fid) - Kill fid a -> do - forks <- liftEffect (Ref.read s.forks) - traverse_ (Aff.killFiber (Aff.error "Cancelled")) (Map.lookup fid forks) - pure a - --- | A simpler interface for building the components eval function. The main lifecycle events map directly into --- | actions, so only the action handling logic needs to be written using `HaloM`. -type EvalSpec props state action m = - { handleAction :: action -> HaloM props state action m Unit - , initialize :: Maybe action - , update :: props -> Maybe action - , finalize :: Maybe action - } - --- | The empty `EvalSpec`. -defaultEval :: forall props action state m. EvalSpec props state action m -defaultEval = - { handleAction: \_ -> pure unit - , initialize: Nothing - , update: \_ -> Nothing - , finalize: Nothing - } - --- | Given an `EvalSpec` builder, it will return an eval function. -mkEval :: forall props state action m. EvalSpec props state action m -> Lifecycle props action -> HaloM props state action m Unit -mkEval eval = case _ of - Initialize -> traverse_ eval.handleAction eval.initialize - Update props -> traverse_ eval.handleAction $ eval.update props - Action action -> eval.handleAction action - Finalize -> traverse_ eval.handleAction eval.finalize - --- | Simple way to run Aff logic asynchronously, while bringing errors back into Effect. -runAff :: Aff Unit -> Effect Unit -runAff = Aff.runAff_ (either throwError pure) - -runInitialize :: forall props state action. HaloState props action state -> Effect Unit -runInitialize hs@(HaloState s) = - runAff $ evalHaloM hs $ s.eval Initialize - -handleUpdate :: forall props state action. HaloState props action state -> props -> Effect Unit -handleUpdate hs@(HaloState s) newProps = do - prevProps <- Ref.read s.props - unless (unsafeRefEq newProps prevProps) do - Ref.write newProps s.props - runAff $ evalHaloM hs $ s.eval $ Update prevProps - -handleAction :: forall props state action. HaloState props state action -> action -> Effect Unit -handleAction hs@(HaloState s) action = - unlessM (Ref.read s.finalized) do - runAff $ evalHaloM hs $ s.eval $ Action action - -runFinalize :: forall props state action. HaloState props state action -> Effect Unit -runFinalize hs@(HaloState s) = do - Ref.write true s.finalized - subscriptions <- Ref.modify' (\s' -> { state: Map.empty, value: s' }) s.subscriptions - traverse_ unsubscribe (Map.values subscriptions) - forks <- Ref.modify' (\s' -> { state: Map.empty, value: s' }) s.forks - traverse_ (runAff <<< Aff.killFiber (Aff.error "Cancelled")) (Map.values forks) - runAff $ evalHaloM hs $ s.eval Finalize diff --git a/src/React/Halo/Internal/Runtime.purs b/src/React/Halo/Internal/Runtime.purs new file mode 100644 index 0000000..5af769f --- /dev/null +++ b/src/React/Halo/Internal/Runtime.purs @@ -0,0 +1,928 @@ +module React.Halo.Internal.Runtime + ( HaloAp + , HaloM + , Handlers + , Runtime + , activate + , createRuntime + , deactivate + , dispatch + , fork + , getProps + , kill + , managedComplete + , managedReset + , managedStart + , registerCleanup + , releaseCleanup + , subscribe + , subscribeWithId + , syncSpec + , unsubscribe + , updateProps + ) where + +import Prelude + +import Control.Monad.Error.Class (class MonadThrow, throwError) +import Control.Monad.Reader (ReaderT(..), class MonadAsk, ask, mapReaderT) +import Control.Monad.State.Class (class MonadState) +import Control.Monad.Trans.Class (class MonadTrans, lift) +import Control.Monad.Writer (class MonadTell, tell) +import Control.Parallel (class Parallel, parallel, sequential) +import Data.Either (Either(..)) +import Data.Foldable (foldM, foldl, traverse_) +import Data.Map (Map) +import Data.Map as Map +import Data.Maybe (Maybe(..)) +import Data.Traversable (traverse) +import Data.Tuple (Tuple(..)) +import Effect (Effect) +import Effect.Aff (Aff, Error, Fiber, ParAff) +import Effect.Aff as Aff +import Effect.Aff.AVar as AVar +import Effect.Aff.Class (class MonadAff, liftAff) +import Effect.AVar as EffectAVar +import Effect.Class (class MonadEffect, liftEffect) +import Effect.Exception as Exception +import Effect.Ref (Ref) +import Effect.Ref as Ref +import React.Halo.Internal.Task.Types (Binding, Token, View) +import React.Halo.Internal.Task.Types as Task +import React.Halo.Internal.Types (CleanupId(..), ErrorContext(..), ForkId(..), RuntimeId(..), SubscriptionId(..)) +import React.Halo.Subscription (Emitter) +import React.Halo.Subscription as Subscription +import Unsafe.Reference (unsafeRefEq) + +-- | A sequential component computation over an application monad `m`. +-- | +-- | Standard `lift` runs an `m` value through the interpreter supplied to +-- | `component` or `useHalo`. Every lift checks the current ownership fence, so +-- | killed or deactivated work cannot begin another application effect. HaloM +-- | also provides component `MonadState`; its other lifted capabilities, such +-- | as `MonadEffect`, `MonadAff`, `MonadAsk`, `MonadTell`, and `MonadThrow`, pass +-- | through `m`. +newtype HaloM props state action (m :: Type -> Type) a = HaloM + (ReaderT (Execution props state action m) Aff a) + +-- | The abstract parallel applicative counterpart of `HaloM`. +-- | +-- | Parallel branches share one root, component scope, and application +-- | interpreter snapshot. Concurrent component-state writes have +-- | nondeterministic ordering; prefer combining independent application results +-- | before one state update. +newtype HaloAp props state action (m :: Type -> Type) a = HaloAp + (ReaderT (Execution props state action m) ParAff a) + +derive newtype instance functorHaloM :: Functor (HaloM props state action m) +derive newtype instance applyHaloM :: Apply (HaloM props state action m) +derive newtype instance applicativeHaloM :: Applicative (HaloM props state action m) +derive newtype instance bindHaloM :: Bind (HaloM props state action m) +derive newtype instance monadHaloM :: Monad (HaloM props state action m) + +derive newtype instance functorHaloAp :: Functor (HaloAp props state action m) +derive newtype instance applyHaloAp :: Apply (HaloAp props state action m) +derive newtype instance applicativeHaloAp :: Applicative (HaloAp props state action m) + +instance monadTransHaloM :: MonadTrans (HaloM props state action) where + lift value = HaloM $ ReaderT \execution -> do + current <- liftEffect $ isCurrent execution + if current then + case execution.runInAff of + RunInAff run -> run value + else Aff.throwError scopeCancellationError + +-- Public effect capabilities deliberately pass through the application monad. +instance monadEffectHaloM :: MonadEffect m => MonadEffect (HaloM props state action m) where + liftEffect = lift <<< liftEffect + +instance monadAffHaloM :: MonadAff m => MonadAff (HaloM props state action m) where + liftAff = lift <<< liftAff + +instance monadAskHaloM :: MonadAsk r m => MonadAsk r (HaloM props state action m) where + ask = lift ask + +instance monadTellHaloM :: MonadTell w m => MonadTell w (HaloM props state action m) where + tell = lift <<< tell + +instance monadThrowHaloM :: MonadThrow error m => MonadThrow error (HaloM props state action m) where + throwError = lift <<< throwError + +instance parallelHaloM :: Parallel (HaloAp props state action m) (HaloM props state action m) where + parallel (HaloM computation) = HaloAp (mapReaderT parallel computation) + sequential (HaloAp computation) = HaloM (mapReaderT sequential computation) + +instance monadStateHaloM :: MonadState state (HaloM props state action m) where + state updateState = HaloM $ ReaderT \execution -> + liftEffect do + current <- isCurrent execution + let Runtime runtime = execution.runtime + oldState <- Ref.read runtime.state + let Tuple result newState = updateState oldState + if current then do + unless (unsafeRefEq oldState newState) do + commitReconciledState execution newState + pure result + else pure result + +-- | Activation, prop-change, and action callbacks. +-- | +-- | Every invocation starts an independent root in the current React +-- | activation. Handlers can overlap and are cancelled when that activation +-- | deactivates. `onPropsChange` receives the previous props; `getProps` reads +-- | the current props. +type Handlers props state action m = + { onActivate :: HaloM props state action m Unit + , onPropsChange :: props -> HaloM props state action m Unit + , onAction :: action -> HaloM props state action m Unit + } + +type RuntimeSpec props state action m = + { handlers :: Handlers props state action m + , onError :: ErrorContext props action -> Error -> Effect Unit + } + +newtype RunInAff m = RunInAff (m ~> Aff) + +newtype Runtime props state action m = Runtime + { bindings :: Ref (Map String (Binding state)) + , fresh :: Ref Int + , needsStatePublish :: Ref Boolean + , props :: Ref props + , runInAff :: Ref (RunInAff m) + , runtimeId :: RuntimeId + , scope :: Ref (Maybe Scope) + , spec :: Ref (RuntimeSpec props state action m) + , state :: Ref state + , stateUpdate :: Ref (state -> View state -> Effect Unit) + } + +newtype Scope = Scope + { active :: Ref Boolean + , authorities :: Ref (Map String Token) + , cleanups :: Ref (Map CleanupId (Effect Unit)) + , forks :: Ref (Map ForkId Root) + , generation :: Int + , handlers :: Ref (Map Int Root) + , subscriptions :: Ref (Map SubscriptionId (Effect Unit)) + } + +newtype Owner = Owner + { alive :: Ref Boolean } + +newtype Root = Root + { fiber :: Fiber Unit + , owner :: Owner + } + +type Execution props state action m = + { context :: ErrorContext props action + , owner :: Owner + , runInAff :: RunInAff m + , runtime :: Runtime props state action m + , scope :: Scope + } + +type Prepared = + { root :: Root + , start :: Effect Unit + } + +createRuntime + :: forall props state action m + . (m ~> Aff) + -> { initialProps :: props + , initialState :: state + , spec :: RuntimeSpec props state action m + , stateUpdate :: state -> View state -> Effect Unit + } + -> Effect (Runtime props state action m) +createRuntime runInAff input = do + bindings <- Ref.new Map.empty + freshRef <- Ref.new 0 + needsStatePublish <- Ref.new false + propsRef <- Ref.new input.initialProps + runInAffRef <- Ref.new (RunInAff runInAff) + runtimeIdentity <- RuntimeId <$> Ref.new unit + scope <- Ref.new Nothing + spec <- Ref.new input.spec + state <- Ref.new input.initialState + stateUpdate <- Ref.new input.stateUpdate + pure $ Runtime + { bindings + , fresh: freshRef + , needsStatePublish + , props: propsRef + , runInAff: runInAffRef + , runtimeId: runtimeIdentity + , scope + , spec + , state + , stateUpdate + } + +-- | Update render-owned callbacks and the interpreter used by roots started +-- | after this synchronization. Running roots retain their interpreter snapshot. +syncSpec + :: forall props state action m + . Runtime props state action m + -> (m ~> Aff) + -> { spec :: RuntimeSpec props state action m + , stateUpdate :: state -> View state -> Effect Unit + } + -> Effect Unit +syncSpec (Runtime runtime) runInAff input = do + Ref.write (RunInAff runInAff) runtime.runInAff + Ref.write input.spec runtime.spec + Ref.write input.stateUpdate runtime.stateUpdate + +activate :: forall props state action m. Runtime props state action m -> Effect Unit +activate runtime@(Runtime state) = do + activeScope <- Ref.read state.scope + case activeScope of + Just _ -> pure unit + Nothing -> do + generation <- fresh runtime + active <- Ref.new true + authorities <- Ref.new Map.empty + cleanups <- Ref.new Map.empty + forks <- Ref.new Map.empty + handlers <- Ref.new Map.empty + subscriptions <- Ref.new Map.empty + let scope = Scope { active, authorities, cleanups, forks, generation, handlers, subscriptions } + Ref.write (Just scope) state.scope + publishRuntimeState runtime + spec <- Ref.read state.spec + startHandler runtime scope ActivationError spec.handlers.onActivate + +deactivate :: forall props state action m. Runtime props state action m -> Effect Unit +deactivate (Runtime state) = do + activeScope <- Ref.read state.scope + case activeScope of + Nothing -> pure unit + Just (Scope current) -> do + Ref.write false current.active + Ref.write Nothing state.scope + + handlers <- takeRef current.handlers Map.empty + forks <- takeRef current.forks Map.empty + cleanups <- takeRef current.cleanups Map.empty + subscriptions <- takeRef current.subscriptions Map.empty + let roots = Map.values handlers <> Map.values forks + + -- Fence every root before normalizing managed state, invoking foreign + -- cleanup, or requesting cooperative Aff cancellation. + traverse_ fenceRoot roots + Ref.write Map.empty current.authorities + normalizeRuntimeState (Runtime state) + cleanupResults <- traverse Exception.try + (Map.values cleanups <> Map.values subscriptions) + traverse_ requestCancel roots + + -- A faulty external cleanup must not prevent any other cleanup request. + spec <- Ref.read state.spec + traverse_ + ( case _ of + Left error -> spec.onError DeactivationError error + Right _ -> pure unit + ) + cleanupResults + +updateProps + :: forall props state action m + . Runtime props state action m + -> props + -> Effect Unit +updateProps runtime@(Runtime state) newProps = do + previousProps <- Ref.read state.props + unless (unsafeRefEq previousProps newProps) do + Ref.write newProps state.props + activeScope <- Ref.read state.scope + traverse_ + ( \scope -> do + spec <- Ref.read state.spec + startHandler runtime scope (PropsChangeError previousProps) (spec.handlers.onPropsChange previousProps) + ) + activeScope + +dispatch + :: forall props state action m + . Runtime props state action m + -> action + -> Effect Unit +dispatch runtime@(Runtime state) action = do + activeScope <- Ref.read state.scope + traverse_ (\scope -> dispatchToScope runtime scope action) activeScope + +dispatchToScope + :: forall props state action m + . Runtime props state action m + -> Scope + -> action + -> Effect Unit +dispatchToScope runtime@(Runtime state) scope action = do + current <- isScopeCurrent runtime scope + when current do + spec <- Ref.read state.spec + startHandler runtime scope (ActionError action) (spec.handlers.onAction action) + +-- | Read the latest component props, rather than the props captured when the +-- | current root started. +getProps :: forall props state action m. HaloM props state action m props +getProps = HaloM $ ReaderT \execution -> do + let Runtime runtime = execution.runtime + liftEffect $ Ref.read runtime.props + +-- | Start a process owned by the current React activation. +-- | +-- | The fork may outlive its launching handler and has an independent +-- | cancellation fence, but it inherits that root's application-interpreter +-- | snapshot. It is cancelled by `kill` or activation deactivation. Unexpected +-- | failure is reported as `ForkError`. +fork + :: forall props state action m + . HaloM props state action m Unit + -> HaloM props state action m ForkId +fork child = HaloM $ ReaderT \execution -> do + fid <- liftEffect $ ForkId <$> fresh execution.runtime + current <- liftEffect $ isCurrent execution + when current do + prepared <- liftEffect $ prepare execution.runInAff execution.runtime execution.scope (ForkError fid) child + { onComplete: do + let Scope scope = execution.scope + Ref.modify_ (Map.delete fid) scope.forks + , onUnexpected: pure unit + } + liftEffect do + let Scope scope = execution.scope + Ref.modify_ (Map.insert fid prepared.root) scope.forks + prepared.start + pure fid + +-- | Cancel a component-owned fork. +-- | +-- | Halo removes and fences the fork synchronously, then waits for Aff +-- | cancellation and finalizers. The fence blocks later state commits, Halo +-- | capabilities, and lifted application effects. An unknown or completed ID +-- | is ignored. +kill + :: forall props state action m + . ForkId + -> HaloM props state action m Unit +kill fid = HaloM $ ReaderT \execution -> do + current <- liftEffect $ isCurrent execution + when current do + let Scope scope = execution.scope + root <- liftEffect $ Ref.modify' + ( \forks -> + { state: Map.delete fid forks + , value: Map.lookup fid forks + } + ) + scope.forks + traverse_ + ( \forkRoot -> do + liftEffect $ fenceRoot forkRoot + cancelRootAff forkRoot + ) + root + +-- Internal managed roots support state-focused lifecycle APIs without exposing +-- root identity. Slot registration, state reconciliation, authority claim, +-- prior-root fencing, replacement registration, and gate opening form one +-- synchronous runtime transaction. +managedStart + :: forall props state action m + . Binding state + -> Maybe (Aff Unit) + -> ( RuntimeId + -> Int + -> ForkId + -> Maybe Token + -> state + -> Maybe + { cancel :: Maybe Token + , computation :: HaloM props state action m Unit + , state :: state + , token :: Token + } + ) + -> HaloM props state action m Unit +managedStart binding privateDelay claim = HaloM $ ReaderT \execution -> + liftEffect do + current <- isCurrent execution + when current do + let + runtime@(Runtime runtimeState) = execution.runtime + Scope scope = execution.scope + brand = Task.bindingBrand binding + oldState <- Ref.read runtimeState.state + registerTaskBinding runtime binding oldState + reconciled <- reconcileExecution execution oldState + displacedRoots <- takeAndFenceTokens execution.scope reconciled.displaced + fid <- ForkId <$> fresh runtime + case + claim runtimeState.runtimeId scope.generation fid + (Map.lookup brand reconciled.authorities) + reconciled.state + of + Nothing -> do + Ref.write reconciled.authorities scope.authorities + when reconciled.changed do + writeAndPublish runtime execution.scope reconciled.state + traverse_ requestCancel displacedRoots + Just managed -> do + prepared <- prepare execution.runInAff runtime execution.scope (ForkError fid) + (withPrivateDelay privateDelay managed.computation) + { onComplete: Ref.modify_ (Map.delete fid) scope.forks + , onUnexpected: exitManaged runtime execution.scope binding managed.token + } + previousRoots <- takeAndFenceTokens execution.scope case managed.cancel of + Nothing -> [] + Just token -> [ token ] + let authorities = Map.insert brand managed.token reconciled.authorities + Ref.write authorities scope.authorities + Ref.write managed.state runtimeState.state + Ref.modify_ (Map.insert fid prepared.root) scope.forks + publishState runtime execution.scope managed.state + traverse_ requestCancel (displacedRoots <> previousRoots) + prepared.start + +-- Commit a typed managed result only while the canonical focus and runtime +-- authority both contain the exact token. The root remains tracked until its +-- ordinary completion finalizer removes it. +managedComplete + :: forall props state action m + . Binding state + -> Token + -> (state -> Maybe state) + -> HaloM props state action m Unit +managedComplete binding token transition = HaloM $ ReaderT \execution -> + liftEffect do + current <- isCurrent execution + when current do + let + runtime@(Runtime runtimeState) = execution.runtime + Scope scope = execution.scope + brand = Task.bindingBrand binding + authorities <- Ref.read scope.authorities + case Map.lookup brand authorities of + Just authoritative | Task.sameToken token authoritative -> do + oldState <- Ref.read runtimeState.state + case transition oldState of + Nothing -> pure unit + Just newState -> do + Ref.write (Map.delete brand authorities) scope.authorities + Ref.write newState runtimeState.state + publishState runtime execution.scope newState + _ -> pure unit + +-- Stop managed work after atomically publishing its replacement state. A root +-- that resets itself is cancelled by unwinding its own fiber rather than trying +-- to join itself. +managedReset + :: forall props state action m + . Binding state + -> ( RuntimeId + -> Int + -> Maybe Token + -> state + -> Maybe + { cancel :: Maybe Token + , state :: state + } + ) + -> HaloM props state action m Unit +managedReset binding transition = HaloM $ ReaderT \execution -> do + current <- liftEffect $ isCurrent execution + when current do + cancellation <- liftEffect do + let + runtime@(Runtime runtimeState) = execution.runtime + Scope scope = execution.scope + brand = Task.bindingBrand binding + oldState <- Ref.read runtimeState.state + registerTaskBinding runtime binding oldState + reconciled <- reconcileExecution execution oldState + displacedRoots <- takeAndFenceTokens execution.scope reconciled.displaced + case + transition runtimeState.runtimeId scope.generation + (Map.lookup brand reconciled.authorities) + reconciled.state + of + Nothing -> do + Ref.write reconciled.authorities scope.authorities + when reconciled.changed do + writeAndPublish runtime execution.scope reconciled.state + traverse_ requestCancel displacedRoots + pure Nothing + Just next -> do + root <- takeAndFenceTokens execution.scope case next.cancel of + Nothing -> [] + Just token -> [ token ] + let authorities = Map.delete brand reconciled.authorities + Ref.write authorities scope.authorities + Ref.write next.state runtimeState.state + publishState runtime execution.scope next.state + traverse_ requestCancel displacedRoots + pure case root of + [ managedRoot ] -> Just managedRoot + _ -> Nothing + traverse_ + ( \managedRoot -> + if sameOwner execution.owner managedRoot then + Aff.throwError scopeCancellationError + else cancelRootAff managedRoot + ) + cancellation + +-- | Register synchronous `Effect` cleanup in the current activation scope. +-- | +-- | Deactivation attempts every remaining cleanup after fencing scope roots. +-- | Cleanup failures are isolated and reported as `DeactivationError` through +-- | the latest error callback. +registerCleanup + :: forall props state action m + . Effect Unit + -> HaloM props state action m CleanupId +registerCleanup cleanup = HaloM $ ReaderT \execution -> do + cid <- liftEffect $ CleanupId <$> fresh execution.runtime + current <- liftEffect $ isCurrent execution + when current do + liftEffect do + let Scope scope = execution.scope + Ref.modify_ (Map.insert cid cleanup) scope.cleanups + pure cid + +-- | Remove tracked cleanup before running it. Unknown or already released IDs +-- | are ignored. A throwing cleanup cannot be retried during deactivation and +-- | follows the error context of the handler or fork that releases it. +releaseCleanup + :: forall props state action m + . CleanupId + -> HaloM props state action m Unit +releaseCleanup cid = HaloM $ ReaderT \execution -> do + current <- liftEffect $ isCurrent execution + when current do + let Scope scope = execution.scope + cleanup <- liftEffect $ Ref.modify' + ( \cleanups -> + { state: Map.delete cid cleanups + , value: Map.lookup cid cleanups + } + ) + scope.cleanups + liftEffect $ traverse_ identity cleanup + +-- | Register an action emitter in the current activation scope. +-- | +-- | Its synchronous cleanup runs on manual unsubscription or deactivation. +-- | Emissions stay bound to the activation that registered them, so a retained +-- | stale callback cannot dispatch into a later activation. +subscribe + :: forall props state action m + . Emitter action + -> HaloM props state action m SubscriptionId +subscribe = subscribeWithId <<< const + +-- | Subscribe while providing the allocated identifier to the emitter's +-- | registration logic. +subscribeWithId + :: forall props state action m + . (SubscriptionId -> Emitter action) + -> HaloM props state action m SubscriptionId +subscribeWithId makeEmitter = HaloM $ ReaderT \execution -> do + sid <- liftEffect $ SubscriptionId <$> fresh execution.runtime + current <- liftEffect $ isCurrent execution + when current do + cleanup <- liftEffect $ Subscription.runEmitter (makeEmitter sid) + (dispatchToScope execution.runtime execution.scope) + liftEffect do + let Scope scope = execution.scope + Ref.modify_ (Map.insert sid cleanup) scope.subscriptions + pure sid + +-- | Remove a tracked subscription before running its cleanup. +-- | +-- | A throwing cleanup therefore cannot be retried during deactivation; when +-- | called from a root, the failure is routed through that root's error context. +unsubscribe + :: forall props state action m + . SubscriptionId + -> HaloM props state action m Unit +unsubscribe sid = HaloM $ ReaderT \execution -> do + current <- liftEffect $ isCurrent execution + when current do + let Scope scope = execution.scope + subscription <- liftEffect $ Ref.modify' + ( \subscriptions -> + { state: Map.delete sid subscriptions + , value: Map.lookup sid subscriptions + } + ) + scope.subscriptions + liftEffect $ traverse_ identity subscription + +startHandler + :: forall props state action m + . Runtime props state action m + -> Scope + -> ErrorContext props action + -> HaloM props state action m Unit + -> Effect Unit +startHandler runtime@(Runtime state) scope@(Scope current) context computation = do + runId <- fresh runtime + runInAff <- Ref.read state.runInAff + prepared <- prepare runInAff runtime scope context computation + { onComplete: Ref.modify_ (Map.delete runId) current.handlers + , onUnexpected: pure unit + } + Ref.modify_ (Map.insert runId prepared.root) current.handlers + prepared.start + +prepare + :: forall props state action m + . RunInAff m + -> Runtime props state action m + -> Scope + -> ErrorContext props action + -> HaloM props state action m Unit + -> { onComplete :: Effect Unit + , onUnexpected :: Effect Unit + } + -> Effect Prepared +prepare runInAff runtime scope context computation hooks = do + owner <- createOwner + gate <- EffectAVar.empty + fiber <- Aff.launchAff do + void $ AVar.take gate + Aff.finally + ( liftEffect do + let Owner current = owner + Ref.write false current.alive + hooks.onComplete + ) + do + outcome <- Aff.attempt $ Aff.supervise $ + runHaloM { context, owner, runInAff, runtime, scope } computation + case outcome of + Left error -> do + current <- liftEffect $ isCurrent { context, owner, runInAff, runtime, scope } + when current do + liftEffect hooks.onUnexpected + let Runtime state = runtime + spec <- liftEffect $ Ref.read state.spec + liftEffect $ spec.onError context error + Right _ -> pure unit + pure + { root: Root { fiber, owner } + , start: Aff.launchAff_ (AVar.put unit gate) + } + +runHaloM + :: forall props state action m a + . Execution props state action m + -> HaloM props state action m a + -> Aff a +runHaloM execution (HaloM computation) = case computation of + ReaderT run -> run execution + +withPrivateDelay + :: forall props state action m a + . Maybe (Aff Unit) + -> HaloM props state action m a + -> HaloM props state action m a +withPrivateDelay privateDelay computation = HaloM $ ReaderT \execution -> do + traverse_ identity privateDelay + runHaloM execution computation + +type ReconciledState state = + { authorities :: Map String Token + , changed :: Boolean + , displaced :: Array Token + , state :: state + } + +registerTaskBinding + :: forall props state action m + . Runtime props state action m + -> Binding state + -> state + -> Effect Unit +registerTaskBinding (Runtime runtime) binding componentState = do + bindings <- Ref.read runtime.bindings + let brand = Task.bindingBrand binding + case Map.lookup brand bindings of + Just existing -> do + sameFocus <- Task.sameBindingFocus componentState existing binding + unless sameFocus $ Exception.throw $ + "Halo task slot \"" <> brand <> "\" is already bound to a different state focus" + Nothing -> do + collision <- foldM + ( \found existing -> case found of + Just _ -> pure found + Nothing -> do + sameFocus <- Task.sameBindingFocus componentState existing binding + pure if sameFocus then Just (Task.bindingBrand existing) else Nothing + ) + Nothing + (Map.values bindings) + case collision of + Just existingBrand -> Exception.throw $ + "Halo task slot \"" <> brand <> "\" overlaps state focus bound as \"" <> existingBrand <> "\"" + Nothing -> Ref.write (Map.insert brand binding bindings) runtime.bindings + +reconcileExecution + :: forall props state action m + . Execution props state action m + -> state + -> Effect (ReconciledState state) +reconcileExecution execution componentState = do + let + Runtime runtime = execution.runtime + Scope scope = execution.scope + bindings <- Ref.read runtime.bindings + authorities <- Ref.read scope.authorities + pure $ reconcileBindings bindings authorities componentState + +reconcileBindings + :: forall state + . Map String (Binding state) + -> Map String Token + -> state + -> ReconciledState state +reconcileBindings bindings authorities componentState = + foldl reconcileOne + { authorities + , changed: false + , displaced: [] + , state: componentState + } + (Map.values bindings) + where + reconcileOne current binding = + let + brand = Task.bindingBrand binding + result = Task.reconcileBinding binding (Map.lookup brand current.authorities) current.state + nextAuthorities = case result.authority of + Nothing -> Map.delete brand current.authorities + Just token -> Map.insert brand token current.authorities + displaced = case result.displaced of + Nothing -> current.displaced + Just token -> current.displaced <> [ token ] + in + { authorities: nextAuthorities + , changed: current.changed || result.changed || case result.displaced of + Nothing -> false + Just _ -> true + , displaced + , state: result.state + } + +commitReconciledState + :: forall props state action m + . Execution props state action m + -> state + -> Effect Unit +commitReconciledState execution proposedState = do + let + runtime@(Runtime runtimeState) = execution.runtime + Scope scope = execution.scope + reconciled <- reconcileExecution execution proposedState + displacedRoots <- takeAndFenceTokens execution.scope reconciled.displaced + Ref.write reconciled.authorities scope.authorities + Ref.write reconciled.state runtimeState.state + publishState runtime execution.scope reconciled.state + traverse_ requestCancel displacedRoots + +normalizeRuntimeState :: forall props state action m. Runtime props state action m -> Effect Unit +normalizeRuntimeState (Runtime runtime) = do + bindings <- Ref.read runtime.bindings + currentState <- Ref.read runtime.state + let reconciled = reconcileBindings bindings Map.empty currentState + when reconciled.changed do + Ref.write reconciled.state runtime.state + Ref.write true runtime.needsStatePublish + +exitManaged + :: forall props state action m + . Runtime props state action m + -> Scope + -> Binding state + -> Token + -> Effect Unit +exitManaged runtime@(Runtime runtimeState) scope@(Scope scopeState) binding token = do + authorities <- Ref.read scopeState.authorities + let brand = Task.bindingBrand binding + case Map.lookup brand authorities of + Just current | Task.sameToken token current -> do + oldState <- Ref.read runtimeState.state + case Task.clearBinding binding token oldState of + Nothing -> pure unit + Just newState -> do + Ref.write (Map.delete brand authorities) scopeState.authorities + Ref.write newState runtimeState.state + publishState runtime scope newState + _ -> pure unit + +publishRuntimeState :: forall props state action m. Runtime props state action m -> Effect Unit +publishRuntimeState runtime@(Runtime runtimeState) = do + needsPublish <- Ref.read runtimeState.needsStatePublish + when needsPublish do + Ref.write false runtimeState.needsStatePublish + currentState <- Ref.read runtimeState.state + activeScope <- Ref.read runtimeState.scope + case activeScope of + Nothing -> pure unit + Just scope -> publishState runtime scope currentState + +writeAndPublish + :: forall props state action m + . Runtime props state action m + -> Scope + -> state + -> Effect Unit +writeAndPublish runtime@(Runtime runtimeState) scope componentState = do + Ref.write componentState runtimeState.state + publishState runtime scope componentState + +publishState + :: forall props state action m + . Runtime props state action m + -> Scope + -> state + -> Effect Unit +publishState (Runtime runtime) (Scope scope) componentState = do + authorities <- Ref.read scope.authorities + update <- Ref.read runtime.stateUpdate + update componentState (Task.makeView componentState authorities) + +takeAndFenceTokens :: Scope -> Array Token -> Effect (Array Root) +takeAndFenceTokens (Scope scope) = foldM takeOne [] + where + takeOne roots token = do + let fid = Task.tokenForkId token + root <- Ref.modify' + ( \forks -> + { state: Map.delete fid forks + , value: Map.lookup fid forks + } + ) + scope.forks + traverse_ fenceRoot root + pure $ roots <> case root of + Nothing -> [] + Just managedRoot -> [ managedRoot ] + +createOwner :: Effect Owner +createOwner = do + alive <- Ref.new true + pure $ Owner { alive } + +fenceRoot :: Root -> Effect Unit +fenceRoot (Root root) = do + let Owner owner = root.owner + Ref.write false owner.alive + +sameOwner :: Owner -> Root -> Boolean +sameOwner (Owner left) (Root right) = case right.owner of + Owner owner -> unsafeRefEq left.alive owner.alive + +requestCancel :: Root -> Effect Unit +requestCancel root = Aff.launchAff_ (cancelRootAff root) + +cancelRootAff :: Root -> Aff Unit +cancelRootAff root@(Root current) = do + liftEffect $ fenceRoot root + Aff.killFiber scopeCancellationError current.fiber + +scopeCancellationError :: Error +scopeCancellationError = Aff.error "Halo scope cancelled" + +isCurrent + :: forall props state action m + . Execution props state action m + -> Effect Boolean +isCurrent execution = do + let Owner owner = execution.owner + ownerAlive <- Ref.read owner.alive + scopeCurrent <- isScopeCurrent execution.runtime execution.scope + pure (ownerAlive && scopeCurrent) + +isScopeCurrent + :: forall props state action m + . Runtime props state action m + -> Scope + -> Effect Boolean +isScopeCurrent (Runtime runtime) (Scope scope) = do + scopeActive <- Ref.read scope.active + activeScope <- Ref.read runtime.scope + pure $ scopeActive && case activeScope of + Just (Scope active) -> active.generation == scope.generation + Nothing -> false + +fresh :: forall props state action m. Runtime props state action m -> Effect Int +fresh (Runtime runtime) = Ref.modify' (\value -> { state: value + 1, value }) runtime.fresh + +takeRef :: forall a. Ref a -> a -> Effect a +takeRef ref replacement = Ref.modify' (\value -> { state: replacement, value }) ref diff --git a/src/React/Halo/Internal/State.purs b/src/React/Halo/Internal/State.purs deleted file mode 100644 index 6185267..0000000 --- a/src/React/Halo/Internal/State.purs +++ /dev/null @@ -1,46 +0,0 @@ -module React.Halo.Internal.State where - -import Prelude -import Data.Map (Map) -import Data.Map as Map -import Effect (Effect) -import Effect.Aff (Aff, Fiber) -import Effect.Ref (Ref) -import Effect.Ref as Ref -import Halogen.Subscription (Subscription) -import React.Halo.Internal.Control (HaloM) -import React.Halo.Internal.Types (ForkId, Lifecycle, SubscriptionId) - --- | The Halo component state used during evaluation. -newtype HaloState props state action = HaloState - { eval :: Lifecycle props action -> HaloM props state action Aff Unit - , update :: state -> Effect Unit - , finalized :: Ref Boolean - , props :: Ref props - , state :: Ref state - , fresh :: Ref Int - , subscriptions :: Ref (Map SubscriptionId Subscription) - , forks :: Ref (Map ForkId (Fiber Unit)) - } - --- | Creates a starting `HaloState`, ready for initialization. -createInitialState - :: forall props state action - . { props :: props - , state :: state - , eval :: Lifecycle props action -> HaloM props state action Aff Unit - , update :: state -> Effect Unit - } - -> Effect (HaloState props state action) -createInitialState spec@{ eval, update } = do - finalized <- Ref.new false - fresh' <- Ref.new 0 - props <- Ref.new spec.props - state <- Ref.new spec.state - subscriptions <- Ref.new Map.empty - forks <- Ref.new Map.empty - pure $ HaloState { eval, update, finalized, props, state, fresh: fresh', subscriptions, forks } - --- | Issue a new identifier, unique to this component. -fresh :: forall props state action a. (Int -> a) -> HaloState props state action -> Effect a -fresh f (HaloState s) = Ref.modify' (\a -> { state: a + 1, value: f a }) s.fresh diff --git a/src/React/Halo/Internal/Task.purs b/src/React/Halo/Internal/Task.purs new file mode 100644 index 0000000..0fba712 --- /dev/null +++ b/src/React/Halo/Internal/Task.purs @@ -0,0 +1,131 @@ +module React.Halo.Internal.Task + ( debounce + , debounceWith + , once + , reset + , startIfInactive + , supersede + ) where + +import Prelude + +import Data.Either (Either) +import Data.Maybe (Maybe(..)) +import Effect.Aff (Aff, Milliseconds(..)) +import Effect.Aff as Aff +import React.Halo.Internal.Runtime (HaloM, managedComplete, managedReset, managedStart) +import React.Halo.Internal.Task.Types (Slot) +import React.Halo.Internal.Task.Types as Task + +data Policy + = Once + | IfInactive + | Supersede + +-- | Start only from `Idle`. Typed failure and success remain terminal until +-- | `reset`. +once + :: forall name props componentState action m error result + . Slot name componentState error result + -> HaloM props componentState action m (Either error result) + -> HaloM props componentState action m Unit +once = launch Once Nothing + +-- | Start from `Idle`, `Failed`, or `Succeeded`, but preserve active work. +startIfInactive + :: forall name props componentState action m error result + . Slot name componentState error result + -> HaloM props componentState action m (Either error result) + -> HaloM props componentState action m Unit +startIfInactive = launch IfInactive Nothing + +-- | Make a new invocation authoritative immediately, fencing and requesting +-- | cancellation of prior managed work without waiting for its finalizers. +supersede + :: forall name props componentState action m error result + . Slot name componentState error result + -> HaloM props componentState action m (Either error result) + -> HaloM props componentState action m Unit +supersede = launch Supersede Nothing + +-- | Trailing-edge latest-wins task invocation. The private cancellable timer and +-- | the executing body both project to `Active`. +debounce + :: forall name props componentState action m error result + . Slot name componentState error result + -> Milliseconds + -> HaloM props componentState action m (Either error result) + -> HaloM props componentState action m Unit +debounce = debounceWith Aff.delay + +-- Internal deterministic timer seam used by runtime tests. +debounceWith + :: forall name props componentState action m error result + . (Milliseconds -> Aff Unit) + -> Slot name componentState error result + -> Milliseconds + -> HaloM props componentState action m (Either error result) + -> HaloM props componentState action m Unit +debounceWith schedule target duration = + launch Supersede (Just (schedule (nonNegative duration))) target + +-- | Clear terminal state or cancel authoritative active work. Cancellation is +-- | fenced synchronously and waits for Aff finalizers before returning. +reset + :: forall name props componentState action m error result + . Slot name componentState error result + -> HaloM props componentState action m Unit +reset target = managedReset (Task.bindingOf target) \_ _ authority componentState -> + case Task.statusAt target authority componentState of + Task.Idle -> Nothing + Task.Active -> Just + { cancel: authority + , state: Task.idleSlot target componentState + } + Task.Failed _ -> Just + { cancel: Nothing + , state: Task.idleSlot target componentState + } + Task.Succeeded _ -> Just + { cancel: Nothing + , state: Task.idleSlot target componentState + } + +launch + :: forall name props componentState action m error result + . Policy + -> Maybe (Aff Unit) + -> Slot name componentState error result + -> HaloM props componentState action m (Either error result) + -> HaloM props componentState action m Unit +launch policy privateDelay target body = + managedStart (Task.bindingOf target) privateDelay \runtimeId generation forkId authority componentState -> do + let + status = Task.statusAt target authority componentState + canStart = case policy of + Once -> case status of + Task.Idle -> true + _ -> false + IfInactive -> case status of + Task.Active -> false + _ -> true + Supersede -> true + if canStart then do + let + token = Task.makeToken target runtimeId generation forkId + taskBody = do + outcome <- body + managedComplete (Task.bindingOf target) token + (Task.completeSlot target token outcome) + pure + { cancel: case policy of + Supersede -> authority + _ -> Nothing + , computation: taskBody + , state: Task.activateSlot target token componentState + , token + } + else Nothing + +nonNegative :: Milliseconds -> Milliseconds +nonNegative (Milliseconds duration) = Milliseconds (max 0.0 duration) diff --git a/src/React/Halo/Internal/Task/Types.purs b/src/React/Halo/Internal/Task/Types.purs new file mode 100644 index 0000000..70bb012 --- /dev/null +++ b/src/React/Halo/Internal/Task/Types.purs @@ -0,0 +1,383 @@ +module React.Halo.Internal.Task.Types + ( Binding + , Slot + , State + , Status(..) + , Token + , View + , _Active + , _Failed + , _Idle + , _Succeeded + , activateSlot + , bindingBrand + , bindingOf + , clearBinding + , completeSlot + , emptyView + , idle + , idleSlot + , isActive + , makeToken + , makeView + , reconcileBinding + , sameBindingFocus + , sameToken + , slot + , slotAt + , slotBrand + , statusAt + , toMaybe + , toStatus + , tokenForkId + ) where + +import Prelude + +import Data.Either (Either(..)) +import Data.Lens (ALens', Prism', prism', withLens) +import Data.Lens.Record (prop) +import Data.Map (Map) +import Data.Map as Map +import Data.Maybe (Maybe(..)) +import Data.Symbol (class IsSymbol, reflectSymbol) +import Effect (Effect) +import Effect.Ref (Ref) +import Effect.Ref as Ref +import Prim.Row as Row +import React.Halo.Internal.Types (ForkId, RuntimeId(..)) +import Type.Proxy (Proxy) +import Unsafe.Reference (unsafeRefEq) + +-- | Public task lifecycle. Runtime ownership remains hidden in `State` and +-- | `View`. +data Status error result + = Idle + | Active + | Failed error + | Succeeded result + +derive instance eqStatus :: (Eq error, Eq result) => Eq (Status error result) + +instance showStatus :: (Show error, Show result) => Show (Status error result) where + show = case _ of + Idle -> "Idle" + Active -> "Active" + Failed error -> "(Failed " <> show error <> ")" + Succeeded result -> "(Succeeded " <> show result <> ")" + +newtype Probe = Probe (Ref Unit) + +newtype Token = Token + { brand :: String + , forkId :: ForkId + , generation :: Int + , runtimeId :: RuntimeId + } + +data Lifecycle error result + = LifecycleIdle + | LifecycleActive Token + | LifecycleFailed error + | LifecycleSucceeded result + | LifecycleProbe Probe + +-- | Freely copyable task lifecycle state. Active authority is validated against +-- | a runtime `View`; the value alone does not own a managed root. +newtype State error result = State + { brand :: String + , lifecycle :: Lifecycle error result + } + +-- | An identity-bearing optic for one task state focus. The name brands values +-- | while the lens locates the canonical component-state field. +data Slot (name :: Symbol) componentState error result = Slot + { binding :: Binding componentState + , brand :: String + , get :: componentState -> State error result + , set :: componentState -> State error result -> componentState + } + +type role Slot nominal representational representational representational + +-- | Immutable task-authority snapshot published with component state. +newtype View state = View + { authorities :: Map String Token + , state :: state + } + +newtype Binding state = Binding + { brand :: String + , clear :: Token -> state -> Maybe state + , mark :: Probe -> state -> state + , reconcile :: + Maybe Token + -> state + -> { authority :: Maybe Token + , changed :: Boolean + , displaced :: Maybe Token + , state :: state + } + , sees :: Probe -> state -> Boolean + } + +-- | Construct a task slot for the record field named by the type-level label. +-- | The same label supplies both the slot brand and its lawful record lens. +slot + :: forall name row componentRow error result + . IsSymbol name + => Row.Cons name (State error result) row componentRow + => Proxy name + -> Slot name (Record componentRow) error result +slot proxy = slotAt proxy (prop proxy) + +-- | Construct a branded task slot for a nested or custom lawful focus. +-- | +-- | On first policy use, a runtime binds the brand to the lens focus. Reusing a +-- | brand at another focus or another brand at the same focus fails in the +-- | calling root's existing error context before mutation or cancellation. +slotAt + :: forall name componentState error result + . IsSymbol name + => Proxy name + -> ALens' componentState (State error result) + -> Slot name componentState error result +slotAt proxy target = withLens target \get set -> + let + brand = reflectSymbol proxy + binding = Binding + { brand + , clear: \token componentState -> case get componentState of + State task -> case task.lifecycle of + LifecycleActive current + | task.brand == brand && sameToken token current -> + Just $ set componentState (State { brand, lifecycle: LifecycleIdle }) + _ -> Nothing + , mark: \probe componentState -> + set componentState (State { brand, lifecycle: LifecycleProbe probe }) + , reconcile: reconcileFocus brand get set + , sees: \probe componentState -> case get componentState of + State task -> case task.lifecycle of + LifecycleProbe candidate -> sameProbe probe candidate + _ -> false + } + in + Slot { binding, brand, get, set } + +-- | Construct correctly branded idle state for a slot. +idle :: forall name state error result. Slot name state error result -> State error result +idle (Slot target) = State { brand: target.brand, lifecycle: LifecycleIdle } + +-- | Project one slot through an immutable runtime view. +toStatus + :: forall name state error result + . View state + -> Slot name state error result + -> Status error result +toStatus (View snapshot) target@(Slot slotState) = + statusAt target (Map.lookup slotState.brand snapshot.authorities) snapshot.state + +-- | Return a slot's authoritative successful result, if present. +toMaybe + :: forall name state error result + . View state + -> Slot name state error result + -> Maybe result +toMaybe taskView target = case toStatus taskView target of + Succeeded result -> Just result + _ -> Nothing + +-- | Test whether a slot has an authoritative debounce timer or task body. +isActive + :: forall name state error result + . View state + -> Slot name state error result + -> Boolean +isActive taskView target = case toStatus taskView target of + Active -> true + _ -> false + +_Idle :: forall error result. Prism' (Status error result) Unit +_Idle = prism' (const Idle) case _ of + Idle -> Just unit + _ -> Nothing + +_Active :: forall error result. Prism' (Status error result) Unit +_Active = prism' (const Active) case _ of + Active -> Just unit + _ -> Nothing + +_Failed :: forall error result. Prism' (Status error result) error +_Failed = prism' Failed case _ of + Failed error -> Just error + _ -> Nothing + +_Succeeded :: forall error result. Prism' (Status error result) result +_Succeeded = prism' Succeeded case _ of + Succeeded result -> Just result + _ -> Nothing + +bindingOf :: forall name state error result. Slot name state error result -> Binding state +bindingOf (Slot target) = target.binding + +bindingBrand :: forall state. Binding state -> String +bindingBrand (Binding binding) = binding.brand + +clearBinding :: forall state. Binding state -> Token -> state -> Maybe state +clearBinding (Binding binding) = binding.clear + +slotBrand :: forall name state error result. Slot name state error result -> String +slotBrand (Slot target) = target.brand + +makeToken + :: forall name state error result + . Slot name state error result + -> RuntimeId + -> Int + -> ForkId + -> Token +makeToken (Slot target) runtimeId generation forkId = Token + { brand: target.brand + , forkId + , generation + , runtimeId + } + +tokenForkId :: Token -> ForkId +tokenForkId (Token token) = token.forkId + +sameToken :: Token -> Token -> Boolean +sameToken (Token left) (Token right) = + left.brand == right.brand + && left.generation == right.generation + && left.forkId == right.forkId + && sameRuntime left.runtimeId right.runtimeId + +statusAt + :: forall name state error result + . Slot name state error result + -> Maybe Token + -> state + -> Status error result +statusAt (Slot target) authority componentState = case target.get componentState of + State task + | task.brand /= target.brand -> Idle + | otherwise -> case task.lifecycle of + LifecycleIdle -> Idle + LifecycleActive token -> case authority of + Just current | sameToken token current -> Active + _ -> Idle + LifecycleFailed error -> Failed error + LifecycleSucceeded result -> Succeeded result + LifecycleProbe _ -> Idle + +activateSlot + :: forall name state error result + . Slot name state error result + -> Token + -> state + -> state +activateSlot (Slot target) token componentState = + target.set componentState (State { brand: target.brand, lifecycle: LifecycleActive token }) + +idleSlot + :: forall name state error result + . Slot name state error result + -> state + -> state +idleSlot target@(Slot current) componentState = current.set componentState (idle target) + +completeSlot + :: forall name state error result + . Slot name state error result + -> Token + -> Either error result + -> state + -> Maybe state +completeSlot (Slot target) token outcome componentState = case target.get componentState of + State task -> case task.lifecycle of + LifecycleActive current + | task.brand == target.brand && sameToken token current -> + Just $ target.set componentState $ State + { brand: target.brand + , lifecycle: case outcome of + Left error -> LifecycleFailed error + Right result -> LifecycleSucceeded result + } + _ -> Nothing + +emptyView :: forall state. state -> View state +emptyView state = View { authorities: Map.empty, state } + +makeView :: forall state. state -> Map String Token -> View state +makeView state authorities = View { authorities, state } + +sameBindingFocus :: forall state. state -> Binding state -> Binding state -> Effect Boolean +sameBindingFocus componentState (Binding left) (Binding right) = do + probeRef <- Ref.new unit + let probe = Probe probeRef + pure $ + left.sees probe (right.mark probe componentState) + && right.sees probe (left.mark probe componentState) + +reconcileBinding + :: forall state + . Binding state + -> Maybe Token + -> state + -> { authority :: Maybe Token + , changed :: Boolean + , displaced :: Maybe Token + , state :: state + } +reconcileBinding (Binding binding) = binding.reconcile + +reconcileFocus + :: forall state error result + . String + -> (state -> State error result) + -> (state -> State error result -> state) + -> Maybe Token + -> state + -> { authority :: Maybe Token + , changed :: Boolean + , displaced :: Maybe Token + , state :: state + } +reconcileFocus brand get set authority componentState = + let + State task = get componentState + correctBrand = task.brand == brand + exactActive = case task.lifecycle, authority of + LifecycleActive token, Just current -> correctBrand && sameToken token current + _, _ -> false + validInactive = correctBrand && case task.lifecycle of + LifecycleIdle -> true + LifecycleFailed _ -> true + LifecycleSucceeded _ -> true + _ -> false + in + if exactActive then + { authority + , changed: false + , displaced: Nothing + , state: componentState + } + else if validInactive then + { authority: Nothing + , changed: false + , displaced: authority + , state: componentState + } + else + { authority: Nothing + , changed: true + , displaced: authority + , state: set componentState (State { brand, lifecycle: LifecycleIdle }) + } + +sameProbe :: Probe -> Probe -> Boolean +sameProbe (Probe left) (Probe right) = unsafeRefEq left right + +sameRuntime :: RuntimeId -> RuntimeId -> Boolean +sameRuntime (RuntimeId left) (RuntimeId right) = unsafeRefEq left right diff --git a/src/React/Halo/Internal/Types.purs b/src/React/Halo/Internal/Types.purs index 32b3f17..3d6a8f9 100644 --- a/src/React/Halo/Internal/Types.purs +++ b/src/React/Halo/Internal/Types.purs @@ -1,28 +1,57 @@ -module React.Halo.Internal.Types where +module React.Halo.Internal.Types + ( CleanupId(..) + , ErrorContext(..) + , ForkId(..) + , RuntimeId(..) + , SubscriptionId(..) + ) where import Prelude --- | The Halo lifecycle events. --- | --- | - `Initialize` contains the initial props. It occurs when the component mounts, and only once per component. --- | - `Update` contains the previous and new props. It occurs when the component re-renders and the props have changes. --- | - `Action` contains the dispatched action. It occurs each time an action is dispatched to be eval'd, up until the --- | `Finalize` event. --- | - `Finalize` occurs when the component unmounts. -data Lifecycle props action - = Initialize - | Update props - | Action action - | Finalize +import Effect.Ref (Ref) -newtype SubscriptionId = SubscriptionId Int +-- | Identifies synchronous cleanup in one React activation. Its constructor is +-- | hidden from the root `React.Halo` API. +newtype CleanupId = CleanupId Int -derive newtype instance eqSubscriptionId :: Eq SubscriptionId +derive newtype instance eqCleanupId :: Eq CleanupId -derive newtype instance ordSubscriptionId :: Ord SubscriptionId +derive newtype instance ordCleanupId :: Ord CleanupId +derive newtype instance showCleanupId :: Show CleanupId + +-- | Identifies the component-owned computation or cleanup whose unexpected +-- | failure reached `onError`. +-- | +-- | `PropsChangeError` carries the previous props, `ActionError` carries the +-- | dispatched action, and `ForkError` carries the component-owned fork ID. +-- | Halo-initiated cancellation is fenced and is not reported. +data ErrorContext props action + = ActivationError + | PropsChangeError props + | ActionError action + | ForkError ForkId + | DeactivationError + +-- Runtime identity used only by internal ownership tokens. +newtype RuntimeId = RuntimeId (Ref Unit) + +-- | Identifies a component-owned process created with `fork`. Its constructor +-- | is hidden from the root `React.Halo` API. newtype ForkId = ForkId Int derive newtype instance eqForkId :: Eq ForkId derive newtype instance ordForkId :: Ord ForkId + +derive newtype instance showForkId :: Show ForkId + +-- | Identifies an emitter subscription in one React activation. Its constructor +-- | is hidden from the root `React.Halo` API. +newtype SubscriptionId = SubscriptionId Int + +derive newtype instance eqSubscriptionId :: Eq SubscriptionId + +derive newtype instance ordSubscriptionId :: Ord SubscriptionId + +derive newtype instance showSubscriptionId :: Show SubscriptionId diff --git a/src/React/Halo/Subscription.purs b/src/React/Halo/Subscription.purs new file mode 100644 index 0000000..c4d3907 --- /dev/null +++ b/src/React/Halo/Subscription.purs @@ -0,0 +1,42 @@ +module React.Halo.Subscription + ( Emitter + , makeEmitter + , runEmitter + ) where + +import Prelude (Unit, class Functor, (<<<)) + +import Effect (Effect) + +-- | A source that broadcasts actions to each registered receiver. +-- | +-- | Registration returns synchronous cleanup for that receiver. Halo runs it +-- | when the subscription is removed or its React activation ends. A receiver +-- | remains bound to the activation that registered it, so a stale callback +-- | cannot dispatch into a later activation. Emitters do not provide a +-- | consuming queue or backpressure. +newtype Emitter action = Emitter + ((action -> Effect Unit) -> Effect (Effect Unit)) + +-- | Transform each emitted value before it reaches the receiver. Mapping keeps +-- | the source's registration and cleanup behavior unchanged. +instance functorEmitter :: Functor Emitter where + map transform (Emitter register) = Emitter \receive -> + register (receive <<< transform) + +-- | Create an emitter from registration logic. During deactivation, a throwing +-- | cleanup is isolated from the remaining scope cleanup and reported as +-- | `DeactivationError`. +makeEmitter + :: forall action + . ((action -> Effect Unit) -> Effect (Effect Unit)) + -> Emitter action +makeEmitter = Emitter + +-- | Register a receiver and obtain its cleanup effect. +runEmitter + :: forall action + . Emitter action + -> (action -> Effect Unit) + -> Effect (Effect Unit) +runEmitter (Emitter register) = register diff --git a/src/React/Halo/Task.purs b/src/React/Halo/Task.purs new file mode 100644 index 0000000..5f997d5 --- /dev/null +++ b/src/React/Halo/Task.purs @@ -0,0 +1,19 @@ +-- | Typed lifecycle state for component-owned Halo work. +-- | +-- | Import this module qualified. A branded `Slot` is an identity-bearing +-- | optic for one `State error result` field; it is not a computation, input, +-- | fork handle, or cache definition. Policy bodies remain ordinary `HaloM` +-- | values that return `Either error result`. +-- | +-- | `State` is freely copyable, so active authority is validated through the +-- | immutable `View` published with each Halo render. Observe a slot with +-- | `toStatus`, `toMaybe`, or `isActive`. Expected `Left` values become +-- | `Failed`; unexpected exceptions return the task to `Idle` and follow Halo's +-- | normal `ForkError` routing. +module React.Halo.Task + ( module Policies + , module Types + ) where + +import React.Halo.Internal.Task (debounce, once, reset, startIfInactive, supersede) as Policies +import React.Halo.Internal.Task.Types (Slot, State, Status(..), View, _Active, _Failed, _Idle, _Succeeded, idle, isActive, slot, slotAt, toMaybe, toStatus) as Types diff --git a/test/Main.purs b/test/Main.purs index 0ba98f2..fcb7f0a 100644 --- a/test/Main.purs +++ b/test/Main.purs @@ -1,134 +1,18 @@ module Test.Main where import Prelude -import Control.Monad.State (modify_, put) -import Data.Maybe (Maybe(..)) + import Effect (Effect) -import Effect.Aff (Milliseconds(..), delay, launchAff_, parallel, sequential) -import Effect.Aff.Class (liftAff) -import Effect.Class (liftEffect) -import Effect.Ref as Ref -import React.Halo as Halo -import React.Halo.Internal.Eval as Eval -import React.Halo.Internal.State as State -import Test.Spec (Spec, describe, it) -import Test.Spec.Assertions (shouldEqual) +import Test.Halo.ScopeHandlerSpec as ScopeHandlerSpec +import Test.Halo.RuntimeSpec as RuntimeSpec +import Test.Halo.SubscriptionErrorSpec as SubscriptionErrorSpec +import Test.Halo.TaskSpec as TaskSpec import Test.Spec.Reporter (consoleReporter) -import Test.Spec.Runner (runSpec) +import Test.Spec.Runner.Node (runSpecAndExitProcess) main :: Effect Unit -main = - launchAff_ do - runSpec [ consoleReporter ] do - describe "purescript-react-halo" do - describe "Props" runPropTests - describe "State" runStateTests - describe "Subscriptions" runSubscriptionTests - describe "Parallelism" runParallelismTests - describe "Forking" runForkingTests - -runPropTests :: Spec Unit -runPropTests = do - describe "Update" do - it "does not fire in initialization" do - { expect } <- makeUpdateState - expect 0 - it "does not fire when props are referentially equal" do - { state, initialProps, expect } <- makeUpdateState - liftEffect $ Eval.handleUpdate state initialProps - expect 0 - it "does fire when props are not referentially equal" do - { state, expect } <- makeUpdateState - liftEffect $ Eval.handleUpdate state { value: "new object" } - expect 1 - where - makeUpdateState = - liftEffect do - count <- Ref.new 0 - let - eval = case _ of - Halo.Update _ -> liftEffect $ Ref.modify_ (add 1) count - _ -> pure unit - - initialProps = { value: "" } - - expect x = liftEffect (Ref.read count) >>= shouldEqual x - state <- State.createInitialState { props: initialProps, state: unit, eval, update: mempty } - Eval.runInitialize state - pure { state, initialProps, expect } - -runStateTests :: Spec Unit -runStateTests = do - it "correctly modifies the state" do - { modify, expect, read } <- makeState { value: "" } - modify \s -> s { value = "first" } - modify \s -> s { value = s.value <> " test" } - value <- read - value `shouldEqual` { value: "first test" } - expect 2 - it "does not modify the state when the reference has not changed" do - { modify, expect, read } <- makeState { value: "" } - modify identity - value <- read - value `shouldEqual` { value: "" } - expect 0 - where - makeState initialState = - liftEffect do - count <- Ref.new 0 - value <- Ref.new initialState - let - update state = do - Ref.write state value - Ref.modify_ (add 1) count - - read = liftEffect $ Ref.read value - - expect x = liftEffect (Ref.read count) >>= shouldEqual x - - eval = case _ of - Halo.Action f -> modify_ f - _ -> pure unit - state <- State.createInitialState { props: unit, state: initialState, eval, update } - Eval.runInitialize state - let - modify = liftEffect <<< Eval.handleAction state - pure { expect, modify, state, read } - -runSubscriptionTests :: Spec Unit -runSubscriptionTests = pure unit - -runParallelismTests :: Spec Unit -runParallelismTests = do - it "should run logic in parallel" do - state <- - liftEffect do - internalState <- Ref.new Nothing - state <- - State.createInitialState - { props: unit - , state: 0 - , update: \x -> Ref.write (Just x) internalState - , eval: - \_ -> do - c <- - sequential ado - a <- - parallel do - liftAff $ delay $ Milliseconds 1_000.0 - pure 1 - b <- - parallel do - liftAff $ delay $ Milliseconds 1_000.0 - pure 2 - in a + b - put c - } - Eval.runInitialize state - pure internalState - delay $ Milliseconds 1_100.0 - c <- liftEffect $ Ref.read state - c `shouldEqual` (Just 3) - -runForkingTests :: Spec Unit -runForkingTests = pure unit +main = runSpecAndExitProcess [ consoleReporter ] do + RuntimeSpec.spec + ScopeHandlerSpec.spec + SubscriptionErrorSpec.spec + TaskSpec.spec diff --git a/test/Test/Halo/DocExamples.purs b/test/Test/Halo/DocExamples.purs new file mode 100644 index 0000000..ebb4a5b --- /dev/null +++ b/test/Test/Halo/DocExamples.purs @@ -0,0 +1,107 @@ +module Test.Halo.DocExamples where + +import Prelude + +import Control.Monad.Reader (ReaderT, ask, runReaderT) +import Control.Monad.State (modify_) +import Control.Monad.Trans.Class (lift) +import Data.Either (Either(..)) +import Effect.Aff (Aff) +import Effect.Aff.Class (class MonadAff, liftAff) +import Effect.Class (class MonadEffect) +import Effect.Class.Console as Console +import Effect.Exception (message) +import React.Basic.DOM as R +import React.Basic.DOM.Events (capture_) +import React.Basic.Hooks (Component, Hook) +import React.Halo as Halo +import React.Halo.Task as Task +import Type.Proxy (Proxy(..)) + +type Env = { loadGreeting :: Aff String } + +newtype AppM a = AppM (ReaderT Env Aff a) + +derive newtype instance functorAppM :: Functor AppM +derive newtype instance applyAppM :: Apply AppM +derive newtype instance applicativeAppM :: Applicative AppM +derive newtype instance bindAppM :: Bind AppM +derive newtype instance monadAppM :: Monad AppM +derive newtype instance monadEffectAppM :: MonadEffect AppM +derive newtype instance monadAffAppM :: MonadAff AppM + +runAppM :: Env -> AppM ~> Aff +runAppM env (AppM computation) = runReaderT computation env + +loadGreeting :: AppM String +loadGreeting = AppM do + env <- ask + liftAff env.loadGreeting + +type Props = { title :: String } + +type State = { greeting :: String } + +initialState :: State +initialState = { greeting: "Not loaded" } + +data Action = LoadGreeting + +type UI a = Halo.HaloM Props State Action AppM a + +handlers :: Halo.Handlers Props State Action AppM +handlers = Halo.defaultHandlers + { onAction = case _ of + LoadGreeting -> do + greeting <- lift loadGreeting + modify_ _ { greeting = greeting } + } + +loadButton :: Env -> Component Props +loadButton env = Halo.component "LoadButton" (runAppM env) + { initialState: \_ -> initialState + , handlers + , onError: \_ error -> + Console.error $ message error + , render: \{ props, state, dispatch } -> + R.div_ + [ R.text props.title + , R.button + { onClick: capture_ (dispatch LoadGreeting) + , children: [ R.text "Load" ] + } + , R.text state.greeting + ] + } + +useExample + :: Env + -> Props + -> Hook (Halo.UseHalo Props State Action AppM) (Halo.HaloResult State Action) +useExample env props = Halo.useHalo (runAppM env) + { props + , initialState + , handlers + , onError: \_ _ -> pure unit + } + +type SearchState = { search :: Task.State String String } + +searchSlot :: Task.Slot "search" SearchState String String +searchSlot = Task.slot (Proxy :: Proxy "search") + +data SearchAction = Search String + +searchHandler + :: SearchAction + -> Halo.HaloM Unit SearchState SearchAction Aff Unit +searchHandler = case _ of + Search query -> Task.supersede searchSlot do + pure (Right query) + +renderSearch :: Task.View SearchState -> String +renderSearch tasks = case Task.toStatus tasks searchSlot of + Task.Idle -> "Search" + Task.Active -> "Searching" + Task.Failed error -> error + Task.Succeeded result -> result diff --git a/test/Test/Halo/GuideExamples.purs b/test/Test/Halo/GuideExamples.purs new file mode 100644 index 0000000..3018c20 --- /dev/null +++ b/test/Test/Halo/GuideExamples.purs @@ -0,0 +1,160 @@ +module Test.Halo.GuideExamples where + +import Prelude + +import Control.Monad.State (gets, modify_) +import Control.Monad.Trans.Class (lift) +import Control.Parallel (parallel, sequential) +import Data.Either (Either(..)) +import Data.Foldable (traverse_) +import Data.Lens (Lens', preview) +import Data.Lens.Record (prop) +import Data.Maybe (Maybe(..)) +import Data.Tuple (Tuple(..)) +import Effect (Effect) +import Effect.Aff (Aff, Milliseconds(..)) +import Effect.Exception as Exception +import React.Halo as Halo +import React.Halo.Task as Task +import Type.Proxy (Proxy(..)) + +type DashboardState = + { feed :: Int + , profile :: Int + } + +parallelExample :: Halo.HaloM Unit DashboardState Unit Aff Unit +parallelExample = do + Tuple profile feed <- sequential ado + profile <- parallel $ lift (pure 1 :: Aff Int) + feed <- parallel $ lift (pure 2 :: Aff Int) + in Tuple profile feed + + modify_ _ { profile = profile, feed = feed } + +data FormAction + = NameChanged String + | Save + +type FormState = + { name :: String + , savedName :: Maybe String + } + +formHandler :: FormAction -> Halo.HaloM Unit FormState FormAction Aff Unit +formHandler = case _ of + NameChanged name -> modify_ _ { name = name } + Save -> do + name <- gets _.name + saved <- lift (pure name :: Aff String) + modify_ _ { savedName = Just saved } + +propsHandler + :: { value :: Int } + -> Halo.HaloM { value :: Int } Unit Unit Aff Unit +propsHandler previous = do + current <- Halo.getProps + void $ lift (pure $ previous.value + current.value :: Aff Int) + +type SearchState = + { query :: String + , search :: Task.State String Int + } + +searchSlot :: Task.Slot "search" SearchState String Int +searchSlot = Task.slot (Proxy :: Proxy "search") + +initialSearchState :: SearchState +initialSearchState = + { query: "" + , search: Task.idle searchSlot + } + +search :: String -> Halo.HaloM Unit SearchState Unit Aff (Either String Int) +search query = do + modify_ _ { query = query } + lift (pure (Right 1) :: Aff (Either String Int)) + +taskPolicies :: Halo.HaloM Unit SearchState Unit Aff Unit +taskPolicies = do + Task.once searchSlot (search "initial") + Task.startIfInactive searchSlot (search "save") + Task.supersede searchSlot (search "latest") + Task.debounce searchSlot (Milliseconds 250.0) (search "debounced") + Task.reset searchSlot + +renderSearch :: Task.View SearchState -> String +renderSearch tasks = case Task.toStatus tasks searchSlot of + Task.Idle -> "Search" + Task.Active -> "Searching" + Task.Failed error -> error + Task.Succeeded _ -> "Done" + +successfulSearch :: Task.View SearchState -> Maybe Int +successfulSearch tasks = preview Task._Succeeded (Task.toStatus tasks searchSlot) + +type NestedState = + { tasks :: { search :: Task.State String Int } + } + +tasksLens :: Lens' NestedState { search :: Task.State String Int } +tasksLens = prop (Proxy :: Proxy "tasks") + +nestedSearchLens :: Lens' { search :: Task.State String Int } (Task.State String Int) +nestedSearchLens = prop (Proxy :: Proxy "search") + +nestedSearchSlot :: Task.Slot "nestedSearch" NestedState String Int +nestedSearchSlot = Task.slotAt (Proxy :: Proxy "nestedSearch") (tasksLens <<< nestedSearchLens) + +type ProcessState = { synchronization :: Maybe Halo.ForkId } + +startSynchronization :: Halo.HaloM Unit ProcessState Unit Aff Unit +startSynchronization = do + fiber <- Halo.fork (lift (pure unit :: Aff Unit)) + modify_ _ { synchronization = Just fiber } + +cancelSynchronization :: Halo.HaloM Unit ProcessState Unit Aff Unit +cancelSynchronization = do + current <- gets _.synchronization + traverse_ Halo.kill current + modify_ _ { synchronization = Nothing } + +data ExternalAction = NameReceived String + +names :: Halo.Emitter String +names = Halo.makeEmitter \emit -> do + emit "Halo" + pure (pure unit) + +actions :: Halo.Emitter ExternalAction +actions = NameReceived <$> names + +subscriptionExample :: Halo.HaloM Unit Unit ExternalAction Aff Unit +subscriptionExample = do + subscriptionId <- Halo.subscribeWithId \_ -> actions + Halo.unsubscribe subscriptionId + +cleanupExample + :: Effect Unit + -> Halo.HaloM Unit Unit ExternalAction Aff Unit +cleanupExample removeListener = do + cleanupId <- Halo.registerCleanup removeListener + Halo.releaseCleanup cleanupId + +lifecycleHandlers :: Halo.Handlers Unit Unit ExternalAction Aff +lifecycleHandlers = Halo.defaultHandlers + { onActivate = void $ Halo.subscribe actions + , onPropsChange = \_ -> void Halo.getProps + , onAction = \_ -> pure unit + } + +errorExample + :: Halo.ErrorContext Unit ExternalAction + -> Exception.Error + -> Effect Unit +errorExample context _ = case context of + Halo.ActivationError -> pure unit + Halo.PropsChangeError _ -> pure unit + Halo.ActionError _ -> pure unit + Halo.ForkError _ -> pure unit + Halo.DeactivationError -> pure unit diff --git a/test/Test/Halo/Helpers.purs b/test/Test/Halo/Helpers.purs new file mode 100644 index 0000000..7466da3 --- /dev/null +++ b/test/Test/Halo/Helpers.purs @@ -0,0 +1,55 @@ +module Test.Halo.Helpers + ( Gate + , await + , makeGate + , release + , shouldNotHaveStarted + , waitForGate + ) where + +import Prelude + +import Control.Alt ((<|>)) +import Control.Parallel (parallel, sequential) +import Data.Maybe (Maybe(..)) +import Effect (Effect) +import Effect.Aff (Aff, Milliseconds(..)) +import Effect.Aff as Aff +import Effect.Aff.AVar as AVar +import Effect.AVar (AVar) +import Effect.AVar as EffectAVar +import Test.Spec.Assertions (shouldEqual) + +type Gate = + { release :: AVar Unit + , settled :: AVar Unit + , started :: AVar Unit + } + +makeGate :: Effect Gate +makeGate = do + started <- EffectAVar.empty + releaseGate <- EffectAVar.empty + settled <- EffectAVar.empty + pure { started, release: releaseGate, settled } + +waitForGate :: Gate -> Aff Unit +waitForGate gate = Aff.finally + (void $ AVar.tryPut unit gate.settled) + do + AVar.put unit gate.started + void $ AVar.take gate.release + +await :: forall a. String -> AVar a -> Aff a +await label value = + sequential $ + parallel (AVar.take value) + <|> parallel (Aff.delay (Milliseconds 2_000.0) *> Aff.throwError (Aff.error ("Timed out waiting for " <> label))) + +release :: Gate -> Aff Unit +release = AVar.put unit <<< _.release + +shouldNotHaveStarted :: Gate -> Aff Unit +shouldNotHaveStarted gate = do + started <- AVar.tryTake gate.started + started `shouldEqual` Nothing diff --git a/test/Test/Halo/RuntimeSpec.purs b/test/Test/Halo/RuntimeSpec.purs new file mode 100644 index 0000000..0ed7f67 --- /dev/null +++ b/test/Test/Halo/RuntimeSpec.purs @@ -0,0 +1,191 @@ +module Test.Halo.RuntimeSpec (spec) where + +import Prelude + +import Control.Monad.Reader (ReaderT(..), ask, runReaderT) +import Control.Monad.State (modify_) +import Control.Monad.Trans.Class (lift) +import Control.Parallel (parallel, sequential) +import Data.Tuple (Tuple(..)) +import Effect.Aff (Aff) +import Effect.Aff as Aff +import Effect.Aff.AVar as AVar +import Effect.Aff.Class (class MonadAff, liftAff) +import Effect.AVar (AVar) +import Effect.AVar as EffectAVar +import Effect.Class (class MonadEffect, liftEffect) +import Effect.Ref as Ref +import React.Halo.Handlers (Handlers, defaultHandlers) +import React.Halo.Internal.Runtime (Runtime, activate, createRuntime, deactivate, dispatch, fork, kill, syncSpec) +import React.Halo.Internal.Types (ForkId) +import Test.Halo.Helpers (Gate, await, makeGate, release, waitForGate) +import Test.Spec (Spec, describe, it) +import Test.Spec.Assertions (shouldEqual) + +newtype AppM a = AppM (ReaderT Int Aff a) + +derive newtype instance functorAppM :: Functor AppM +derive newtype instance applyAppM :: Apply AppM +derive newtype instance applicativeAppM :: Applicative AppM +derive newtype instance bindAppM :: Bind AppM +derive newtype instance monadAppM :: Monad AppM +derive newtype instance monadEffectAppM :: MonadEffect AppM +derive newtype instance monadAffAppM :: MonadAff AppM + +runAppM :: Int -> AppM ~> Aff +runAppM environment (AppM computation) = runReaderT computation environment + +readEnvironment :: AppM Int +readEnvironment = AppM ask + +catchGateCancellation :: Gate -> AppM Unit +catchGateCancellation gate = AppM $ ReaderT \_ -> + Aff.catchError (waitForGate gate) (\_ -> pure unit) + +writeExternalWitness :: Ref.Ref Boolean -> AppM Unit +writeExternalWitness witness = AppM $ ReaderT \_ -> + liftEffect $ Ref.write true witness + +data Action + = ReadEnvironment Gate (AVar Int) + | LaunchSnapshotFork Gate Gate (AVar Int) + | LaunchCancellableLift Gate (Ref.Ref Boolean) (AVar ForkId) (AVar Unit) + | KillLift ForkId (AVar Unit) + | RunParallel Gate Gate (AVar Unit) + +type State = Int + +handlers :: Handlers Unit State Action AppM +handlers = defaultHandlers + { onAction = case _ of + ReadEnvironment gate completed -> do + liftAff $ waitForGate gate + environment <- lift readEnvironment + liftAff $ void $ AVar.tryPut environment completed + LaunchSnapshotFork handlerGate childGate completed -> do + liftAff $ waitForGate handlerGate + void $ fork do + liftAff $ waitForGate childGate + environment <- lift readEnvironment + liftAff $ void $ AVar.tryPut environment completed + LaunchCancellableLift gate witness forkId completed -> do + childId <- fork do + lift $ catchGateCancellation gate + lift $ writeExternalWitness witness + liftAff $ void $ AVar.tryPut childId forkId + liftAff $ void $ AVar.tryPut unit completed + KillLift childId completed -> do + kill childId + liftAff $ void $ AVar.tryPut unit completed + RunParallel left right completed -> do + Tuple a b <- sequential ado + a <- parallel do + liftAff $ waitForGate left + pure 1 + b <- parallel do + liftAff $ waitForGate right + pure 2 + in Tuple a b + modify_ (\state -> state + a + b) + liftAff $ void $ AVar.tryPut unit completed + } + +makeRuntime + :: Int + -> Aff + { runtime :: Runtime Unit State Action AppM + , state :: Ref.Ref State + } +makeRuntime environment = liftEffect do + state <- Ref.new 0 + runtime <- createRuntime (runAppM environment) + { initialProps: unit + , initialState: 0 + , spec: { handlers, onError: \_ _ -> pure unit } + , stateUpdate: \next _ -> Ref.write next state + } + activate runtime + pure { runtime, state } + +spec :: Spec Unit +spec = describe "application monad and parallelism" do + it "lifts AppM and snapshots the interpreter for each root" do + { runtime, state } <- makeRuntime 1 + Aff.finally (liftEffect $ deactivate runtime) do + firstGate <- liftEffect makeGate + firstResult <- liftEffect EffectAVar.empty + liftEffect $ dispatch runtime (ReadEnvironment firstGate firstResult) + void $ await "first root start" firstGate.started + + liftEffect $ syncSpec runtime (runAppM 2) + { spec: { handlers, onError: \_ _ -> pure unit } + , stateUpdate: \next _ -> Ref.write next state + } + + secondGate <- liftEffect makeGate + secondResult <- liftEffect EffectAVar.empty + liftEffect $ dispatch runtime (ReadEnvironment secondGate secondResult) + void $ await "second root start" secondGate.started + + release firstGate + release secondGate + first <- await "first environment" firstResult + second <- await "second environment" secondResult + first `shouldEqual` 1 + second `shouldEqual` 2 + + it "gives a later fork its launching handler's interpreter snapshot" do + { runtime, state } <- makeRuntime 1 + Aff.finally (liftEffect $ deactivate runtime) do + handlerGate <- liftEffect makeGate + childGate <- liftEffect makeGate + childResult <- liftEffect EffectAVar.empty + liftEffect $ dispatch runtime (LaunchSnapshotFork handlerGate childGate childResult) + void $ await "snapshot handler start" handlerGate.started + + liftEffect $ syncSpec runtime (runAppM 2) + { spec: { handlers, onError: \_ _ -> pure unit } + , stateUpdate: \next _ -> Ref.write next state + } + + release handlerGate + void $ await "snapshot child start" childGate.started + release childGate + result <- await "snapshot child environment" childResult + result `shouldEqual` 1 + + it "rejects a freshly lifted AppM effect after kill fences its fork" do + { runtime } <- makeRuntime 1 + Aff.finally (liftEffect $ deactivate runtime) do + gate <- liftEffect makeGate + witness <- liftEffect $ Ref.new false + forkId <- liftEffect EffectAVar.empty + launched <- liftEffect EffectAVar.empty + killed <- liftEffect EffectAVar.empty + liftEffect $ dispatch runtime (LaunchCancellableLift gate witness forkId launched) + childId <- await "cancellable AppM fork id" forkId + void $ await "cancellable AppM fork launch" launched + void $ await "cancellable AppM effect start" gate.started + + liftEffect $ dispatch runtime (KillLift childId killed) + void $ await "cancellable AppM fork kill" killed + void $ await "cancelled AppM effect settlement" gate.settled + changed <- liftEffect $ Ref.read witness + changed `shouldEqual` false + + it "runs Halo branches concurrently with the direct Parallel instance" do + { runtime, state } <- makeRuntime 1 + Aff.finally (liftEffect $ deactivate runtime) do + left <- liftEffect makeGate + right <- liftEffect makeGate + completed <- liftEffect EffectAVar.empty + + liftEffect $ dispatch runtime (RunParallel left right completed) + void $ await "left parallel branch" left.started + void $ await "right parallel branch" right.started + + release left + release right + void $ await "parallel handler completion" completed + value <- liftEffect $ Ref.read state + value `shouldEqual` 3 diff --git a/test/Test/Halo/ScopeHandlerSpec.purs b/test/Test/Halo/ScopeHandlerSpec.purs new file mode 100644 index 0000000..503a397 --- /dev/null +++ b/test/Test/Halo/ScopeHandlerSpec.purs @@ -0,0 +1,310 @@ +module Test.Halo.ScopeHandlerSpec (spec) where + +import Prelude + +import Control.Monad.State (modify_) +import Data.Maybe (Maybe(..)) +import Data.Tuple (Tuple(..)) +import Effect (Effect) +import Effect.Aff (Aff) +import Effect.Aff as Aff +import Effect.Aff.AVar as AVar +import Effect.Aff.Class (liftAff) +import Effect.AVar (AVar) +import Effect.AVar as EffectAVar +import Effect.Class (liftEffect) +import Effect.Ref as Ref +import React.Halo.Handlers (defaultHandlers) +import React.Halo.Internal.Runtime (Runtime, activate, createRuntime, deactivate, dispatch, fork, getProps, kill, syncSpec, updateProps) +import React.Halo.Internal.Types (ForkId) +import Test.Halo.Helpers (Gate, await, makeGate, release, shouldNotHaveStarted, waitForGate) +import Test.Spec (Spec, describe, it) +import Test.Spec.Assertions (shouldEqual) + +identityAff :: Aff ~> Aff +identityAff = identity + +spec :: Spec Unit +spec = describe "scope, handlers, and component-owned forks" do + it "cancels roots on deactivation and accepts work after reactivation" do + forkGate <- liftEffect makeGate + forkId <- liftEffect EffectAVar.empty + handlerDone <- liftEffect EffectAVar.empty + pulseDone <- liftEffect EffectAVar.empty + state <- liftEffect $ Ref.new 0 + runtime <- liftEffect $ + ( createRuntime identityAff + { initialProps: unit + , initialState: 0 + , spec: + { handlers: defaultHandlers + { onAction = case _ of + StartScopedFork gate fid completed -> do + child <- fork do + liftAff $ waitForGate gate + modify_ (_ + 1) + liftAff $ void $ AVar.tryPut child fid + liftAff $ void $ AVar.tryPut unit completed + Pulse completed -> do + modify_ (_ + 10) + liftAff $ void $ AVar.tryPut unit completed + } + , onError: \_ _ -> pure unit + } + , stateUpdate: \next _ -> Ref.write next state + } :: Effect (Runtime Unit Int ScopeAction Aff) + ) + + liftEffect do + activate runtime + dispatch runtime (StartScopedFork forkGate forkId handlerDone) + void $ await "fork id" forkId + void $ await "launching handler completion" handlerDone + void $ await "fork before deactivation" forkGate.started + + liftEffect $ deactivate runtime + void $ await "fork cancellation on deactivation" forkGate.settled + valueAfterDeactivate <- liftEffect $ Ref.read state + valueAfterDeactivate `shouldEqual` 0 + + ignored <- liftEffect makeGate + ignoredId <- liftEffect EffectAVar.empty + ignoredDone <- liftEffect EffectAVar.empty + liftEffect $ dispatch runtime (StartScopedFork ignored ignoredId ignoredDone) + shouldNotHaveStarted ignored + + liftEffect do + activate runtime + dispatch runtime (Pulse pulseDone) + void $ await "action after reactivation" pulseDone + valueAfterReactivate <- liftEffect $ Ref.read state + valueAfterReactivate `shouldEqual` 10 + liftEffect $ deactivate runtime + + it "models StrictMode setup-cleanup-setup with repeatable onActivate" do + activation <- liftEffect EffectAVar.empty + pulse <- liftEffect EffectAVar.empty + state <- liftEffect $ Ref.new 0 + runtime <- liftEffect $ + ( createRuntime identityAff + { initialProps: unit + , initialState: 0 + , spec: + { handlers: defaultHandlers + { onActivate = do + modify_ (_ + 1) + liftAff $ void $ AVar.tryPut unit activation + , onAction = \(ReplayPulse completed) -> do + modify_ (_ + 10) + liftAff $ void $ AVar.tryPut unit completed + } + , onError: \_ _ -> pure unit + } + , stateUpdate: \next _ -> Ref.write next state + } :: Effect (Runtime Unit Int ReplayAction Aff) + ) + + Aff.finally (liftEffect $ deactivate runtime) do + liftEffect $ activate runtime + void $ await "first activation" activation + first <- liftEffect $ Ref.read state + first `shouldEqual` 1 + + liftEffect do + deactivate runtime + activate runtime + void $ await "StrictMode replay activation" activation + liftEffect $ dispatch runtime (ReplayPulse pulse) + void $ await "action after StrictMode replay" pulse + second <- liftEffect $ Ref.read state + second `shouldEqual` 12 + + it "passes previous props and exposes current props" do + changed <- liftEffect EffectAVar.empty + runtime <- liftEffect $ + ( createRuntime identityAff + { initialProps: 0 + , initialState: unit + , spec: + { handlers: defaultHandlers + { onPropsChange = \previous -> do + current <- getProps + liftAff $ void $ AVar.tryPut (Tuple previous current) changed + } + , onError: \_ _ -> pure unit + } + , stateUpdate: \_ _ -> pure unit + } :: Effect (Runtime Int Unit Unit Aff) + ) + + Aff.finally (liftEffect $ deactivate runtime) do + liftEffect do + activate runtime + updateProps runtime 1 + values <- await "props change handler" changed + values `shouldEqual` Tuple 0 1 + + it "owns and cancels a running props-change handler" do + gate <- liftEffect makeGate + state <- liftEffect $ Ref.new 0 + runtime <- liftEffect $ + ( createRuntime identityAff + { initialProps: 0 + , initialState: 0 + , spec: + { handlers: defaultHandlers + { onPropsChange = \_ -> do + liftAff $ waitForGate gate + modify_ (_ + 1) + } + , onError: \_ _ -> pure unit + } + , stateUpdate: \next _ -> Ref.write next state + } :: Effect (Runtime Int Int Unit Aff) + ) + + liftEffect do + activate runtime + updateProps runtime 1 + void $ await "props-change handler start" gate.started + liftEffect $ deactivate runtime + void $ await "props-change handler cancellation" gate.settled + value <- liftEffect $ Ref.read state + value `shouldEqual` 0 + + it "lets a component-owned fork outlive its launching handler" do + child <- liftEffect makeGate + forkId <- liftEffect EffectAVar.empty + handlerDone <- liftEffect EffectAVar.empty + state <- liftEffect $ Ref.new 0 + runtime <- liftEffect $ + ( createRuntime identityAff + { initialProps: unit + , initialState: 0 + , spec: + { handlers: defaultHandlers + { onAction = \(LaunchChild gate fid completed) -> do + childId <- fork do + liftAff $ waitForGate gate + modify_ (_ + 1) + liftAff $ void $ AVar.tryPut childId fid + liftAff $ void $ AVar.tryPut unit completed + } + , onError: \_ _ -> pure unit + } + , stateUpdate: \next _ -> Ref.write next state + } :: Effect (Runtime Unit Int ForkAction Aff) + ) + + Aff.finally (liftEffect $ deactivate runtime) do + liftEffect do + activate runtime + dispatch runtime (LaunchChild child forkId handlerDone) + void $ await "child start" child.started + void $ await "launching handler return" handlerDone + settledBeforeRelease <- liftEffect $ EffectAVar.tryTake child.settled + settledBeforeRelease `shouldEqual` Nothing + + release child + void $ await "child completion" child.settled + value <- liftEffect $ Ref.read state + value `shouldEqual` 1 + + it "kill fences commits and capabilities, and waits for finalizers" do + child <- liftEffect makeGate + ignored <- liftEffect makeGate + forkId <- liftEffect EffectAVar.empty + launchDone <- liftEffect EffectAVar.empty + killDone <- liftEffect EffectAVar.empty + state <- liftEffect $ Ref.new 0 + runtime <- liftEffect $ + ( createRuntime identityAff + { initialProps: unit + , initialState: 0 + , spec: + { handlers: defaultHandlers + { onAction = case _ of + LaunchCancellable gate ignoredGate fid completed -> do + childId <- fork do + liftAff $ Aff.catchError (waitForGate gate) (\_ -> pure unit) + void $ fork $ liftAff $ waitForGate ignoredGate + modify_ (_ + 1) + liftAff $ void $ AVar.tryPut childId fid + liftAff $ void $ AVar.tryPut unit completed + KillChild fid completed -> do + kill fid + liftAff $ void $ AVar.tryPut unit completed + } + , onError: \_ _ -> pure unit + } + , stateUpdate: \next _ -> Ref.write next state + } :: Effect (Runtime Unit Int CancelAction Aff) + ) + + Aff.finally (liftEffect $ deactivate runtime) do + liftEffect do + activate runtime + dispatch runtime (LaunchCancellable child ignored forkId launchDone) + fid <- await "cancellable fork id" forkId + void $ await "cancellable fork launch" launchDone + void $ await "cancellable fork start" child.started + + liftEffect $ dispatch runtime (KillChild fid killDone) + void $ await "kill completion" killDone + finalizerRan <- liftEffect $ EffectAVar.tryTake child.settled + finalizerRan `shouldEqual` Just unit + shouldNotHaveStarted ignored + value <- liftEffect $ Ref.read state + value `shouldEqual` 0 + + it "uses the latest handlers for new actions" do + oldCompleted <- liftEffect EffectAVar.empty + newCompleted <- liftEffect EffectAVar.empty + state <- liftEffect $ Ref.new 0 + let + oldHandlers = defaultHandlers + { onAction = \Refresh -> do + modify_ (_ + 1) + liftAff $ void $ AVar.tryPut unit oldCompleted + } + newHandlers = defaultHandlers + { onAction = \Refresh -> do + modify_ (_ + 10) + liftAff $ void $ AVar.tryPut unit newCompleted + } + runtime <- liftEffect $ + ( createRuntime identityAff + { initialProps: unit + , initialState: 0 + , spec: { handlers: oldHandlers, onError: \_ _ -> pure unit } + , stateUpdate: \next _ -> Ref.write next state + } :: Effect (Runtime Unit Int RefreshAction Aff) + ) + + Aff.finally (liftEffect $ deactivate runtime) do + liftEffect do + activate runtime + syncSpec runtime identityAff + { spec: { handlers: newHandlers, onError: \_ _ -> pure unit } + , stateUpdate: \next _ -> Ref.write next state + } + dispatch runtime Refresh + void $ await "new action handler" newCompleted + oldRan <- liftEffect $ EffectAVar.tryTake oldCompleted + oldRan `shouldEqual` Nothing + value <- liftEffect $ Ref.read state + value `shouldEqual` 10 + +data ScopeAction + = StartScopedFork Gate (AVar ForkId) (AVar Unit) + | Pulse (AVar Unit) + +data ReplayAction = ReplayPulse (AVar Unit) + +data ForkAction = LaunchChild Gate (AVar ForkId) (AVar Unit) + +data CancelAction + = LaunchCancellable Gate Gate (AVar ForkId) (AVar Unit) + | KillChild ForkId (AVar Unit) + +data RefreshAction = Refresh diff --git a/test/Test/Halo/SubscriptionErrorSpec.purs b/test/Test/Halo/SubscriptionErrorSpec.purs new file mode 100644 index 0000000..2cc9546 --- /dev/null +++ b/test/Test/Halo/SubscriptionErrorSpec.purs @@ -0,0 +1,454 @@ +module Test.Halo.SubscriptionErrorSpec (spec) where + +import Prelude + +import Control.Monad.State (get, modify_, put) +import Data.Foldable (foldl, traverse_) +import Data.Maybe (Maybe(..)) +import Effect (Effect) +import Effect.Aff (Aff) +import Effect.Aff as Aff +import Effect.Aff.AVar as AVar +import Effect.Aff.Class (liftAff) +import Effect.AVar (AVar) +import Effect.AVar as EffectAVar +import Effect.Class (liftEffect) +import Effect.Exception as Exception +import Effect.Ref as Ref +import React.Halo.Handlers (Handlers, defaultHandlers) +import React.Halo.Internal.Runtime (Runtime, activate, createRuntime, deactivate, dispatch, fork, registerCleanup, releaseCleanup, subscribe, syncSpec, unsubscribe) +import React.Halo.Internal.Types (CleanupId(..), ErrorContext(..), ForkId, SubscriptionId) +import React.Halo.Subscription (Emitter, makeEmitter, runEmitter) +import Test.Halo.Helpers (Gate, await, makeGate, release, waitForGate) +import Test.Spec (Spec, describe, it) +import Test.Spec.Assertions (shouldEqual) + +identityAff :: Aff ~> Aff +identityAff = identity + +spec :: Spec Unit +spec = describe "subscriptions, cleanup, and errors" do + it "maps emitted values while preserving source cleanup" do + received <- liftEffect $ Ref.new [] + cleanupCount <- liftEffect $ Ref.new 0 + let + numbers = makeEmitter \receive -> do + receive 1 + receive 2 + pure $ Ref.modify_ (_ + 1) cleanupCount + actions = (_ + 10) <$> numbers + cleanup <- liftEffect $ runEmitter actions \value -> + Ref.modify_ (_ <> [ value ]) received + liftEffect cleanup + actual <- liftEffect $ Ref.read received + actual `shouldEqual` [ 11, 12 ] + cleaned <- liftEffect $ Ref.read cleanupCount + cleaned `shouldEqual` 1 + + it "releases generic cleanup once and ignores unknown IDs" do + cleanupCount <- liftEffect $ Ref.new 0 + registered <- liftEffect EffectAVar.empty + released <- liftEffect EffectAVar.empty + unknownReleased <- liftEffect EffectAVar.empty + runtime <- liftEffect $ createRuntime identityAff + { initialProps: unit + , initialState: Nothing + , spec: { handlers: subscriptionHandlers, onError: \_ _ -> pure unit } + , stateUpdate: \_ _ -> pure unit + } + + Aff.finally (liftEffect $ deactivate runtime) do + liftEffect do + activate runtime + dispatch runtime (RegisterCleanup (Ref.modify_ (_ + 1) cleanupCount) registered) + cid <- await "generic cleanup registration" registered + liftEffect $ dispatch runtime (ReleaseCleanup cid released) + void $ await "manual generic cleanup release" released + liftEffect $ dispatch runtime (ReleaseCleanup (CleanupId 999_999) unknownReleased) + void $ await "unknown generic cleanup release" unknownReleased + liftEffect $ dispatch runtime (ReleaseCleanup cid released) + void $ await "already released generic cleanup" released + liftEffect $ deactivate runtime + actual <- liftEffect $ Ref.read cleanupCount + actual `shouldEqual` 1 + + it "does not retry a throwing manual cleanup release" do + cleanupRuns <- liftEffect $ Ref.new 0 + registered <- liftEffect EffectAVar.empty + releaseFailed <- liftEffect EffectAVar.empty + errors <- liftEffect $ Ref.new [] + runtime <- liftEffect $ createRuntime identityAff + { initialProps: unit + , initialState: Nothing + , spec: + { handlers: subscriptionHandlers + , onError: \context error -> do + let + label = case context of + ActionError (ReleaseCleanup _ _) -> "release" + _ -> "wrong context" + Ref.modify_ (_ <> [ label <> ": " <> Exception.message error ]) errors + void $ EffectAVar.tryPut unit releaseFailed + } + , stateUpdate: \_ _ -> pure unit + } + + liftEffect do + activate runtime + dispatch runtime + ( RegisterCleanup + (Ref.modify_ (_ + 1) cleanupRuns *> Exception.throw "manual cleanup failed") + registered + ) + cid <- await "throwing cleanup registration" registered + completed <- liftEffect EffectAVar.empty + liftEffect $ dispatch runtime (ReleaseCleanup cid completed) + void $ await "throwing manual cleanup error" releaseFailed + liftEffect $ deactivate runtime + runs <- liftEffect $ Ref.read cleanupRuns + actual <- liftEffect $ Ref.read errors + runs `shouldEqual` 1 + actual `shouldEqual` [ "release: manual cleanup failed" ] + + it "rejects cleanup registration retained by a stale activation" do + cleanupCount <- liftEffect $ Ref.new 0 + gate <- liftEffect makeGate + runtime <- liftEffect $ + ( createRuntime identityAff + { initialProps: unit + , initialState: unit + , spec: + { handlers: staleCleanupHandlers + , onError: \_ _ -> pure unit + } + , stateUpdate: \_ _ -> pure unit + } :: Effect (Runtime Unit Unit StaleCleanupAction Aff) + ) + + liftEffect do + activate runtime + dispatch runtime (RegisterAfterCancellation gate (Ref.modify_ (_ + 1) cleanupCount)) + void $ await "stale cleanup handler" gate.started + liftEffect $ deactivate runtime + void $ await "stale cleanup cancellation" gate.settled + liftEffect do + activate runtime + deactivate runtime + actual <- liftEffect $ Ref.read cleanupCount + actual `shouldEqual` 0 + + it "keeps generic cleanup IDs scoped to one StrictMode activation" do + cleanupCount <- liftEffect $ Ref.new 0 + firstRegistered <- liftEffect EffectAVar.empty + staleReleased <- liftEffect EffectAVar.empty + secondRegistered <- liftEffect EffectAVar.empty + runtime <- liftEffect $ createRuntime identityAff + { initialProps: unit + , initialState: Nothing + , spec: { handlers: subscriptionHandlers, onError: \_ _ -> pure unit } + , stateUpdate: \_ _ -> pure unit + } + + liftEffect do + activate runtime + dispatch runtime (RegisterCleanup (Ref.modify_ (_ + 1) cleanupCount) firstRegistered) + staleId <- await "first activation cleanup" firstRegistered + liftEffect do + deactivate runtime + activate runtime + dispatch runtime (ReleaseCleanup staleId staleReleased) + void $ await "stale cleanup release" staleReleased + liftEffect $ dispatch runtime + (RegisterCleanup (Ref.modify_ (_ + 1) cleanupCount) secondRegistered) + void $ await "second activation cleanup" secondRegistered + liftEffect $ deactivate runtime + actual <- liftEffect $ Ref.read cleanupCount + actual `shouldEqual` 2 + + it "removes a manual unsubscribe from scope tracking" do + cleanupCount <- liftEffect $ Ref.new 0 + started <- liftEffect EffectAVar.empty + stopped <- liftEffect EffectAVar.empty + state <- liftEffect $ Ref.new Nothing + let emitter = makeEmitter \_ -> pure $ Ref.modify_ (_ + 1) cleanupCount + + runtime <- liftEffect $ createRuntime identityAff + { initialProps: unit + , initialState: Nothing + , spec: { handlers: subscriptionHandlers, onError: \_ _ -> pure unit } + , stateUpdate: \next _ -> Ref.write next state + } + + Aff.finally (liftEffect $ deactivate runtime) do + liftEffect do + activate runtime + dispatch runtime (Start emitter started) + void $ await "subscription setup" started + liftEffect $ dispatch runtime (Stop stopped) + void $ await "manual unsubscribe" stopped + + afterManual <- liftEffect $ Ref.read cleanupCount + afterManual `shouldEqual` 1 + liftEffect $ deactivate runtime + afterDeactivation <- liftEffect $ Ref.read cleanupCount + afterDeactivation `shouldEqual` 1 + + it "runs tracked subscription cleanup on deactivation" do + cleanupCount <- liftEffect $ Ref.new 0 + started <- liftEffect EffectAVar.empty + state <- liftEffect $ Ref.new Nothing + let emitter = makeEmitter \_ -> pure $ Ref.modify_ (_ + 1) cleanupCount + + runtime <- liftEffect $ createRuntime identityAff + { initialProps: unit + , initialState: Nothing + , spec: { handlers: subscriptionHandlers, onError: \_ _ -> pure unit } + , stateUpdate: \next _ -> Ref.write next state + } + + Aff.finally (liftEffect $ deactivate runtime) do + liftEffect do + activate runtime + dispatch runtime (Start emitter started) + void $ await "tracked subscription setup" started + liftEffect $ deactivate runtime + cleaned <- liftEffect $ Ref.read cleanupCount + cleaned `shouldEqual` 1 + + it "isolates cleanup failures across generic and subscription resources" do + cleaned <- liftEffect $ Ref.new 0 + oldErrors <- liftEffect $ Ref.new [] + cleanupErrors <- liftEffect $ Ref.new [] + badStarted <- liftEffect EffectAVar.empty + goodStarted <- liftEffect EffectAVar.empty + badCleanupRegistered <- liftEffect EffectAVar.empty + goodCleanupRegistered <- liftEffect EffectAVar.empty + state <- liftEffect $ Ref.new Nothing + gate <- liftEffect makeGate + let + badEmitter = makeEmitter \_ -> pure $ Exception.throw "subscription cleanup failed" + goodEmitter = makeEmitter \_ -> pure $ Ref.modify_ (_ + 1) cleaned + onCleanupError target context error = case context of + DeactivationError -> Ref.modify_ (_ <> [ Exception.message error ]) target + _ -> Ref.modify_ (_ <> [ "wrong error context" ]) target + + runtime <- liftEffect $ createRuntime identityAff + { initialProps: unit + , initialState: Nothing + , spec: + { handlers: subscriptionHandlers + , onError: onCleanupError oldErrors + } + , stateUpdate: \next _ -> Ref.write next state + } + + liftEffect do + activate runtime + dispatch runtime (Start badEmitter badStarted) + void $ await "failing subscription setup" badStarted + liftEffect $ dispatch runtime (Start goodEmitter goodStarted) + void $ await "successful subscription setup" goodStarted + liftEffect $ dispatch runtime + (RegisterCleanup (Exception.throw "generic cleanup failed") badCleanupRegistered) + void $ await "failing generic cleanup setup" badCleanupRegistered + liftEffect $ dispatch runtime + (RegisterCleanup (Ref.modify_ (_ + 1) cleaned) goodCleanupRegistered) + void $ await "successful generic cleanup setup" goodCleanupRegistered + liftEffect $ dispatch runtime (Block gate) + void $ await "running action handler" gate.started + + liftEffect do + syncSpec runtime identityAff + { spec: + { handlers: subscriptionHandlers + , onError: onCleanupError cleanupErrors + } + , stateUpdate: \next _ -> Ref.write next state + } + deactivate runtime + void $ await "running action cancellation" gate.settled + + cleanupCount <- liftEffect $ Ref.read cleaned + cleanupCount `shouldEqual` 2 + previous <- liftEffect $ Ref.read oldErrors + previous `shouldEqual` [] + errors <- liftEffect $ Ref.read cleanupErrors + foldl (\count _ -> count + 1) 0 errors `shouldEqual` 2 + foldl (\found message -> found || message == "generic cleanup failed") false errors `shouldEqual` true + foldl (\found message -> found || message == "subscription cleanup failed") false errors `shouldEqual` true + + it "rejects a callback retained by a stale activation" do + callback <- liftEffect $ Ref.new Nothing + registered <- liftEffect EffectAVar.empty + state <- liftEffect $ Ref.new 0 + let + emitter = makeEmitter \receive -> do + Ref.write (Just receive) callback + pure (pure unit) + handlers = defaultHandlers + { onAction = case _ of + Register completed -> do + void $ subscribe emitter + liftAff $ void $ AVar.tryPut unit completed + Ping -> modify_ (_ + 1) + } + runtime <- liftEffect $ + ( createRuntime identityAff + { initialProps: unit + , initialState: 0 + , spec: { handlers, onError: \_ _ -> pure unit } + , stateUpdate: \next _ -> Ref.write next state + } :: Effect (Runtime Unit Int StaleAction Aff) + ) + + liftEffect do + activate runtime + dispatch runtime (Register registered) + void $ await "stale callback registration" registered + retained <- liftEffect $ Ref.read callback + liftEffect do + deactivate runtime + activate runtime + traverse_ (\receive -> receive Ping) retained + value <- liftEffect $ Ref.read state + value `shouldEqual` 0 + liftEffect $ deactivate runtime + + it "routes action failures and uses the latest onError callback" do + gate <- liftEffect makeGate + oldErrors <- liftEffect $ Ref.new [] + newErrors <- liftEffect $ Ref.new [] + newRaised <- liftEffect EffectAVar.empty + runtime <- liftEffect $ makeErrorRuntime oldErrors + + Aff.finally (liftEffect $ deactivate runtime) do + liftEffect do + activate runtime + dispatch runtime (Boom gate) + void $ await "failing action start" gate.started + + liftEffect $ syncSpec runtime identityAff + { spec: + { handlers: errorHandlers + , onError: \context error -> do + let + label = case context of + ActionError (Boom _) -> "action" + _ -> "wrong context" + Ref.modify_ (_ <> [ label <> ": " <> Exception.message error ]) newErrors + void $ EffectAVar.tryPut unit newRaised + } + , stateUpdate: \_ _ -> pure unit + } + release gate + void $ await "latest action error callback" newRaised + + previous <- liftEffect $ Ref.read oldErrors + current <- liftEffect $ Ref.read newErrors + previous `shouldEqual` [] + current `shouldEqual` [ "action: action boom" ] + + it "routes an unexpected fork failure with ForkError" do + gate <- liftEffect makeGate + forkId <- liftEffect EffectAVar.empty + errors <- liftEffect $ Ref.new [] + raised <- liftEffect EffectAVar.empty + runtime <- liftEffect $ + ( createRuntime identityAff + { initialProps: unit + , initialState: unit + , spec: + { handlers: errorHandlers + , onError: \context error -> do + let + label = case context of + ForkError fid -> "fork " <> show fid + _ -> "wrong context" + Ref.modify_ (_ <> [ label <> ": " <> Exception.message error ]) errors + void $ EffectAVar.tryPut unit raised + } + , stateUpdate: \_ _ -> pure unit + } :: Effect (Runtime Unit Unit ErrorAction Aff) + ) + + Aff.finally (liftEffect $ deactivate runtime) do + liftEffect do + activate runtime + dispatch runtime (ForkBoom gate forkId) + fid <- await "failing fork id" forkId + void $ await "failing fork start" gate.started + release gate + void $ await "fork error callback" raised + actual <- liftEffect $ Ref.read errors + actual `shouldEqual` [ "fork " <> show fid <> ": fork boom" ] + +data SubscriptionAction + = Start (Emitter SubscriptionAction) (AVar Unit) + | Stop (AVar Unit) + | Block Gate + | RegisterCleanup (Effect Unit) (AVar CleanupId) + | ReleaseCleanup CleanupId (AVar Unit) + +type SubscriptionState = Maybe SubscriptionId + +subscriptionHandlers :: Handlers Unit SubscriptionState SubscriptionAction Aff +subscriptionHandlers = defaultHandlers + { onAction = case _ of + Start emitter completed -> do + sid <- subscribe emitter + put (Just sid) + liftAff $ void $ AVar.tryPut unit completed + Stop completed -> do + sid <- get + traverse_ unsubscribe sid + put Nothing + liftAff $ void $ AVar.tryPut unit completed + Block gate -> liftAff $ waitForGate gate + RegisterCleanup cleanup registered -> do + cid <- registerCleanup cleanup + liftAff $ void $ AVar.tryPut cid registered + ReleaseCleanup cid completed -> do + releaseCleanup cid + liftAff $ void $ AVar.tryPut unit completed + } + +data StaleCleanupAction = RegisterAfterCancellation Gate (Effect Unit) + +staleCleanupHandlers :: Handlers Unit Unit StaleCleanupAction Aff +staleCleanupHandlers = defaultHandlers + { onAction = \(RegisterAfterCancellation gate cleanup) -> do + liftAff $ Aff.catchError (waitForGate gate) (\_ -> pure unit) + void $ registerCleanup cleanup + } + +data StaleAction + = Register (AVar Unit) + | Ping + +data ErrorAction + = Boom Gate + | ForkBoom Gate (AVar ForkId) + +errorHandlers :: Handlers Unit Unit ErrorAction Aff +errorHandlers = defaultHandlers + { onAction = case _ of + Boom gate -> do + liftAff $ waitForGate gate + liftAff $ Aff.throwError (Aff.error "action boom") + ForkBoom gate fid -> do + child <- fork do + liftAff $ waitForGate gate + liftAff $ Aff.throwError (Aff.error "fork boom") + liftAff $ void $ AVar.tryPut child fid + } + +makeErrorRuntime :: Ref.Ref (Array String) -> Effect (Runtime Unit Unit ErrorAction Aff) +makeErrorRuntime errors = createRuntime identityAff + { initialProps: unit + , initialState: unit + , spec: + { handlers: errorHandlers + , onError: \_ error -> Ref.modify_ (_ <> [ Exception.message error ]) errors + } + , stateUpdate: \_ _ -> pure unit + } diff --git a/test/Test/Halo/TaskSpec.purs b/test/Test/Halo/TaskSpec.purs new file mode 100644 index 0000000..beac339 --- /dev/null +++ b/test/Test/Halo/TaskSpec.purs @@ -0,0 +1,916 @@ +module Test.Halo.TaskSpec (spec) where + +import Prelude + +import Control.Monad.Reader (ReaderT, ask, runReaderT) +import Control.Monad.State (get, modify_, put) +import Control.Monad.Trans.Class (lift) +import Data.Either (Either(..)) +import Data.Lens (Lens', preview, review) +import Data.Lens.Record (prop) +import Data.Maybe (Maybe(..)) +import Data.Tuple (Tuple(..)) +import Effect (Effect) +import Effect.Aff (Aff, Milliseconds(..)) +import Effect.Aff as Aff +import Effect.Aff.AVar as AVar +import Effect.Aff.Class (liftAff) +import Effect.AVar (AVar) +import Effect.AVar as EffectAVar +import Effect.Class (liftEffect) +import Effect.Exception as Exception +import Effect.Ref as Ref +import React.Halo.Handlers (Handlers, defaultHandlers) +import React.Halo.Internal.Runtime (HaloM, Runtime, activate, createRuntime, deactivate, dispatch, syncSpec) +import React.Halo.Internal.Task as TaskInternal +import React.Halo.Internal.Task.Types as TaskTypes +import React.Halo.Internal.Types (ErrorContext(..)) +import React.Halo.Task as Task +import Test.Halo.Helpers (Gate, await, makeGate, release, shouldNotHaveStarted, waitForGate) +import Test.Spec (Spec, describe, it) +import Test.Spec.Assertions (shouldEqual) +import Type.Proxy (Proxy(..)) + +type ComponentState = + { elsewhere :: Int + , other :: Task.State String Int + , task :: Task.State String Int + } + +taskLens :: Lens' ComponentState (Task.State String Int) +taskLens = prop (Proxy :: Proxy "task") + +taskSlot :: Task.Slot "task" ComponentState String Int +taskSlot = Task.slot (Proxy :: Proxy "task") + +otherLens :: Lens' ComponentState (Task.State String Int) +otherLens = prop (Proxy :: Proxy "other") + +otherSlot :: Task.Slot "other" ComponentState String Int +otherSlot = Task.slot (Proxy :: Proxy "other") + +sameBrandOtherSlot :: Task.Slot "task" ComponentState String Int +sameBrandOtherSlot = Task.slotAt (Proxy :: Proxy "task") otherLens + +differentBrandTaskSlot :: Task.Slot "alias" ComponentState String Int +differentBrandTaskSlot = Task.slotAt (Proxy :: Proxy "alias") taskLens + +data Body + = WaitBody Gate (Either String Int) + | UpdateBody Gate Int (Either String Int) + | UnexpectedBody Gate + | CancellableBody Gate Gate (Ref.Ref Boolean) + +type Timer = + { duration :: AVar Milliseconds + , gate :: Gate + } + +data Action + = RunOnce Body (AVar Unit) + | RunStartIfInactive Body (AVar Unit) + | RunStartTwice Body Body (AVar Unit) + | RunSupersede Body (AVar Unit) + | RunDebounce Timer Milliseconds Body (AVar Unit) + | RunOther Body (AVar Unit) + | Reset (AVar Unit) + | ResetOther (AVar Unit) + | AssignIdleAndStart Body (AVar Unit) + | CopyTaskToOther (AVar Unit) + | CaptureState (AVar ComponentState) + | RestoreState ComponentState (AVar Unit) + | RunSameBrandCollision Body + | RunDifferentBrandCollision Body + +type UI a = HaloM Unit ComponentState Action Aff a + +handlers :: Handlers Unit ComponentState Action Aff +handlers = defaultHandlers + { onAction = case _ of + RunOnce body launched -> do + Task.once taskSlot (runBody body) + signal launched + RunStartIfInactive body launched -> do + Task.startIfInactive taskSlot (runBody body) + signal launched + RunStartTwice first second launched -> do + Task.startIfInactive taskSlot (runBody first) + Task.startIfInactive taskSlot (runBody second) + signal launched + RunSupersede body launched -> do + Task.supersede taskSlot (runBody body) + signal launched + RunDebounce timer duration body launched -> do + TaskInternal.debounceWith (runTimer timer) taskSlot duration (runBody body) + signal launched + RunOther body launched -> do + Task.supersede otherSlot (runBody body) + signal launched + Reset completed -> do + Task.reset taskSlot + signal completed + ResetOther completed -> do + Task.reset otherSlot + signal completed + AssignIdleAndStart body launched -> do + modify_ _ { task = Task.idle taskSlot } + Task.startIfInactive taskSlot (runBody body) + signal launched + CopyTaskToOther completed -> do + modify_ \state -> state { other = state.task } + signal completed + CaptureState captured -> get >>= liftAff <<< void <<< flip AVar.tryPut captured + RestoreState snapshot completed -> do + put snapshot + signal completed + RunSameBrandCollision body -> Task.supersede sameBrandOtherSlot (runBody body) + RunDifferentBrandCollision body -> Task.supersede differentBrandTaskSlot (runBody body) + } + +runBody :: Body -> UI (Either String Int) +runBody = case _ of + WaitBody gate outcome -> do + liftAff $ waitForGate gate + pure outcome + UpdateBody gate amount outcome -> do + liftAff $ waitForGate gate + modify_ \state -> state { elsewhere = state.elsewhere + amount } + pure outcome + UnexpectedBody gate -> do + liftAff $ waitForGate gate + liftAff $ Aff.throwError (Aff.error "task boom") + CancellableBody work finalizer externalWitness -> do + liftAff $ Aff.catchError + (Aff.finally (waitForGate finalizer) (waitForGate work)) + (\_ -> pure unit) + modify_ \state -> state { elsewhere = state.elsewhere + 100 } + liftEffect $ Ref.write true externalWitness + pure (Right 999) + +runTimer :: Timer -> Milliseconds -> Aff Unit +runTimer timer duration = do + AVar.put duration timer.duration + waitForGate timer.gate + +signal :: AVar Unit -> UI Unit +signal completed = liftAff $ void $ AVar.tryPut unit completed + +type Harness = + { otherUpdates :: AVar (Task.Status String Int) + , runtime :: Runtime Unit ComponentState Action Aff + , setterCalls :: Ref.Ref Int + , state :: Ref.Ref ComponentState + , tasks :: Ref.Ref (Task.View ComponentState) + , updates :: AVar (Task.Status String Int) + } + +makeHarness + :: (ErrorContext Unit Action -> Exception.Error -> Effect Unit) + -> Aff Harness +makeHarness onError = liftEffect do + state <- Ref.new initialState + tasks <- Ref.new (TaskTypes.emptyView initialState) + updates <- EffectAVar.empty + otherUpdates <- EffectAVar.empty + setterCalls <- Ref.new 0 + runtime <- createRuntime identity + { initialProps: unit + , initialState + , spec: { handlers, onError } + , stateUpdate: updateState state tasks updates otherUpdates setterCalls + } + activate runtime + pure { otherUpdates, runtime, setterCalls, state, tasks, updates } + +initialState :: ComponentState +initialState = + { elsewhere: 0 + , other: Task.idle otherSlot + , task: Task.idle taskSlot + } + +updateState + :: Ref.Ref ComponentState + -> Ref.Ref (Task.View ComponentState) + -> AVar (Task.Status String Int) + -> AVar (Task.Status String Int) + -> Ref.Ref Int + -> ComponentState + -> Task.View ComponentState + -> Effect Unit +updateState state tasks updates otherUpdates setterCalls next nextTasks = do + previousTasks <- Ref.read tasks + Ref.write next state + Ref.write nextTasks tasks + Ref.modify_ (_ + 1) setterCalls + let + previousStatus = Task.toStatus previousTasks taskSlot + nextStatus = Task.toStatus nextTasks taskSlot + previousOtherStatus = Task.toStatus previousTasks otherSlot + nextOtherStatus = Task.toStatus nextTasks otherSlot + when (previousStatus /= nextStatus) do + void $ EffectAVar.tryPut nextStatus updates + when (previousOtherStatus /= nextOtherStatus) do + void $ EffectAVar.tryPut nextOtherStatus otherUpdates + +awaitStatus + :: String + -> Task.Status String Int + -> AVar (Task.Status String Int) + -> Aff Unit +awaitStatus label expected updates = do + actual <- await label updates + if actual == expected then pure unit + else awaitStatus label expected updates + +makeTimer :: Effect Timer +makeTimer = do + gate <- makeGate + duration <- EffectAVar.empty + pure { duration, gate } + +statusOf :: Harness -> Effect (Task.Status String Int) +statusOf harness = flip Task.toStatus taskSlot <$> Ref.read harness.tasks + +otherStatusOf :: Harness -> Effect (Task.Status String Int) +otherStatusOf harness = flip Task.toStatus otherSlot <$> Ref.read harness.tasks + +spec :: Spec Unit +spec = describe "state-focused tasks" do + it "projects status through helpers and lawful prisms" do + let tasks = TaskTypes.emptyView initialState + Task.toStatus tasks taskSlot `shouldEqual` Task.Idle + Task.toMaybe tasks taskSlot `shouldEqual` Nothing + Task.isActive tasks taskSlot `shouldEqual` false + preview Task._Idle (Task.Idle :: Task.Status String Int) `shouldEqual` Just unit + preview Task._Active (Task.Active :: Task.Status String Int) `shouldEqual` Just unit + preview Task._Failed (Task.Failed "no" :: Task.Status String Int) `shouldEqual` Just "no" + preview Task._Succeeded (Task.Succeeded 4 :: Task.Status String Int) `shouldEqual` Just 4 + review Task._Failed "bad" `shouldEqual` (Task.Failed "bad" :: Task.Status String Int) + review Task._Succeeded 5 `shouldEqual` (Task.Succeeded 5 :: Task.Status String Int) + + it "keeps once terminal until reset and stores typed outcomes" do + harness <- makeHarness \_ _ -> pure unit + Aff.finally (liftEffect $ deactivate harness.runtime) do + first <- liftEffect makeGate + ignored <- liftEffect makeGate + failed <- liftEffect makeGate + firstLaunched <- liftEffect EffectAVar.empty + ignoredLaunched <- liftEffect EffectAVar.empty + failedLaunched <- liftEffect EffectAVar.empty + resetDone <- liftEffect EffectAVar.empty + + liftEffect $ dispatch harness.runtime (RunOnce (WaitBody first (Right 1)) firstLaunched) + void $ await "once launch" firstLaunched + void $ await "once body" first.started + awaitStatus "once active" Task.Active harness.updates + + liftEffect $ dispatch harness.runtime (RunOnce (WaitBody ignored (Right 2)) ignoredLaunched) + void $ await "ignored active once" ignoredLaunched + shouldNotHaveStarted ignored + + release first + void $ await "once body settlement" first.settled + awaitStatus "once success" (Task.Succeeded 1) harness.updates + liftEffect $ dispatch harness.runtime (RunOnce (WaitBody ignored (Right 2)) ignoredLaunched) + shouldNotHaveStarted ignored + + liftEffect $ dispatch harness.runtime (Reset resetDone) + void $ await "terminal reset" resetDone + awaitStatus "reset idle" Task.Idle harness.updates + + liftEffect $ dispatch harness.runtime (RunOnce (WaitBody failed (Left "expected")) failedLaunched) + void $ await "once after reset" failedLaunched + void $ await "failed body" failed.started + awaitStatus "once active after reset" Task.Active harness.updates + release failed + awaitStatus "typed failure" (Task.Failed "expected") harness.updates + + another <- liftEffect makeGate + liftEffect $ dispatch harness.runtime (RunOnce (WaitBody another (Right 3)) ignoredLaunched) + shouldNotHaveStarted another + + it "starts from terminal states only when inactive and claims duplicates atomically" do + harness <- makeHarness \_ _ -> pure unit + Aff.finally (liftEffect $ deactivate harness.runtime) do + first <- liftEffect makeGate + ignored <- liftEffect makeGate + second <- liftEffect makeGate + third <- liftEffect makeGate + launched <- liftEffect EffectAVar.empty + + liftEffect $ dispatch harness.runtime + (RunStartTwice (WaitBody first (Left "first")) (WaitBody ignored (Right 99)) launched) + void $ await "same-turn start calls" launched + void $ await "first inactive body" first.started + shouldNotHaveStarted ignored + awaitStatus "start active" Task.Active harness.updates + release first + awaitStatus "start typed failure" (Task.Failed "first") harness.updates + + liftEffect $ dispatch harness.runtime (RunStartIfInactive (WaitBody second (Right 2)) launched) + void $ await "terminal rerun body" second.started + awaitStatus "terminal replaced" Task.Active harness.updates + release second + awaitStatus "terminal success" (Task.Succeeded 2) harness.updates + + liftEffect $ dispatch harness.runtime (RunStartIfInactive (WaitBody third (Right 3)) launched) + void $ await "success rerun body" third.started + awaitStatus "success replaced" Task.Active harness.updates + release third + awaitStatus "second success" (Task.Succeeded 3) harness.updates + + it "allows bodies to update unrelated component state" do + harness <- makeHarness \_ _ -> pure unit + Aff.finally (liftEffect $ deactivate harness.runtime) do + gate <- liftEffect makeGate + launched <- liftEffect EffectAVar.empty + liftEffect $ dispatch harness.runtime (RunStartIfInactive (UpdateBody gate 7 (Right 8)) launched) + void $ await "updating body" gate.started + awaitStatus "updating task active" Task.Active harness.updates + release gate + awaitStatus "updating task success" (Task.Succeeded 8) harness.updates + state <- liftEffect $ Ref.read harness.state + state.elsewhere `shouldEqual` 7 + + it "supersedes immediately while old finalizers overlap and stale effects stay fenced" do + harness <- makeHarness \_ _ -> pure unit + Aff.finally (liftEffect $ deactivate harness.runtime) do + oldWork <- liftEffect makeGate + oldFinalizer <- liftEffect makeGate + newWork <- liftEffect makeGate + externalWitness <- liftEffect $ Ref.new false + oldLaunched <- liftEffect EffectAVar.empty + newLaunched <- liftEffect EffectAVar.empty + + liftEffect $ dispatch harness.runtime + (RunSupersede (CancellableBody oldWork oldFinalizer externalWitness) oldLaunched) + void $ await "old task launch" oldLaunched + void $ await "old task body" oldWork.started + awaitStatus "old task active" Task.Active harness.updates + + liftEffect $ dispatch harness.runtime (RunSupersede (WaitBody newWork (Right 2)) newLaunched) + void $ await "new superseding launch" newLaunched + void $ await "old finalizer overlap" oldFinalizer.started + void $ await "new task during old finalizer" newWork.started + active <- liftEffect $ statusOf harness + active `shouldEqual` Task.Active + + release newWork + awaitStatus "new task success" (Task.Succeeded 2) harness.updates + externalBeforeRelease <- liftEffect $ Ref.read externalWitness + externalBeforeRelease `shouldEqual` false + stateBeforeRelease <- liftEffect $ Ref.read harness.state + stateBeforeRelease.elsewhere `shouldEqual` 0 + + release oldFinalizer + void $ await "old finalizer settlement" oldFinalizer.settled + externalAfterRelease <- liftEffect $ Ref.read externalWitness + externalAfterRelease `shouldEqual` false + stateAfterRelease <- liftEffect $ Ref.read harness.state + stateAfterRelease.elsewhere `shouldEqual` 0 + statusAfterRelease <- liftEffect $ statusOf harness + statusAfterRelease `shouldEqual` Task.Succeeded 2 + + it "reconciles assigned idle before restart and fences the detached root" do + harness <- makeHarness \_ _ -> pure unit + Aff.finally (liftEffect $ deactivate harness.runtime) do + oldWork <- liftEffect makeGate + oldFinalizer <- liftEffect makeGate + newWork <- liftEffect makeGate + externalWitness <- liftEffect $ Ref.new false + oldLaunched <- liftEffect EffectAVar.empty + newLaunched <- liftEffect EffectAVar.empty + + liftEffect $ dispatch harness.runtime + (RunSupersede (CancellableBody oldWork oldFinalizer externalWitness) oldLaunched) + void $ await "assigned-idle old body" oldWork.started + awaitStatus "assigned-idle old active" Task.Active harness.updates + + liftEffect $ dispatch harness.runtime + (AssignIdleAndStart (WaitBody newWork (Right 11)) newLaunched) + void $ await "assigned-idle restart" newLaunched + awaitStatus "assigned idle publication" Task.Idle harness.updates + void $ await "assigned-idle old finalizer" oldFinalizer.started + void $ await "assigned-idle new body" newWork.started + restartedStatus <- liftEffect $ statusOf harness + restartedStatus `shouldEqual` Task.Active + release newWork + awaitStatus "assigned-idle new success" (Task.Succeeded 11) harness.updates + + release oldFinalizer + void $ await "assigned-idle old settlement" oldFinalizer.settled + witness <- liftEffect $ Ref.read externalWitness + witness `shouldEqual` false + state <- liftEffect $ Ref.read harness.state + state.elsewhere `shouldEqual` 0 + status <- liftEffect $ statusOf harness + status `shouldEqual` Task.Succeeded 11 + + it "normalizes a restored stale snapshot and cancels the displaced authority" do + harness <- makeHarness \_ _ -> pure unit + Aff.finally (liftEffect $ deactivate harness.runtime) do + first <- liftEffect makeGate + currentWork <- liftEffect makeGate + currentFinalizer <- liftEffect makeGate + externalWitness <- liftEffect $ Ref.new false + launched <- liftEffect EffectAVar.empty + captured <- liftEffect EffectAVar.empty + restored <- liftEffect EffectAVar.empty + + liftEffect $ dispatch harness.runtime (RunSupersede (WaitBody first (Right 1)) launched) + void $ await "snapshot first body" first.started + awaitStatus "snapshot first active" Task.Active harness.updates + liftEffect $ dispatch harness.runtime (CaptureState captured) + snapshot <- await "active whole-state snapshot" captured + + liftEffect $ dispatch harness.runtime + (RunSupersede (CancellableBody currentWork currentFinalizer externalWitness) launched) + void $ await "snapshot current body" currentWork.started + void $ await "snapshot old cancellation" first.settled + liftEffect $ dispatch harness.runtime (RestoreState snapshot restored) + void $ await "stale snapshot restoration" restored + void $ await "restored snapshot displaced finalizer" currentFinalizer.started + awaitStatus "restored snapshot idle" Task.Idle harness.updates + + release currentFinalizer + void $ await "displaced current settlement" currentFinalizer.settled + witness <- liftEffect $ Ref.read externalWitness + witness `shouldEqual` false + state <- liftEffect $ Ref.read harness.state + state.elsewhere `shouldEqual` 0 + status <- liftEffect $ statusOf harness + status `shouldEqual` Task.Idle + + it "preserves restored branded terminal state while fencing current work" do + harness <- makeHarness \_ _ -> pure unit + Aff.finally (liftEffect $ deactivate harness.runtime) do + completed <- liftEffect makeGate + currentWork <- liftEffect makeGate + currentFinalizer <- liftEffect makeGate + externalWitness <- liftEffect $ Ref.new false + launched <- liftEffect EffectAVar.empty + captured <- liftEffect EffectAVar.empty + restored <- liftEffect EffectAVar.empty + + liftEffect $ dispatch harness.runtime (RunSupersede (WaitBody completed (Right 4)) launched) + void $ await "terminal snapshot body" completed.started + awaitStatus "terminal snapshot active" Task.Active harness.updates + release completed + awaitStatus "terminal snapshot success" (Task.Succeeded 4) harness.updates + liftEffect $ dispatch harness.runtime (CaptureState captured) + terminalSnapshot <- await "terminal whole-state snapshot" captured + + liftEffect $ dispatch harness.runtime + (RunSupersede (CancellableBody currentWork currentFinalizer externalWitness) launched) + void $ await "terminal replacement current body" currentWork.started + awaitStatus "terminal replacement active" Task.Active harness.updates + liftEffect $ dispatch harness.runtime (RestoreState terminalSnapshot restored) + void $ await "terminal snapshot restoration" restored + void $ await "terminal replacement finalizer" currentFinalizer.started + awaitStatus "restored terminal status" (Task.Succeeded 4) harness.updates + + release currentFinalizer + void $ await "terminal replacement settlement" currentFinalizer.settled + witness <- liftEffect $ Ref.read externalWitness + witness `shouldEqual` false + state <- liftEffect $ Ref.read harness.state + state.elsewhere `shouldEqual` 0 + + it "keeps same-typed slots isolated when active state is copied" do + harness <- makeHarness \_ _ -> pure unit + Aff.finally (liftEffect $ deactivate harness.runtime) do + taskWork <- liftEffect makeGate + otherWork <- liftEffect makeGate + otherAgain <- liftEffect makeGate + launched <- liftEffect EffectAVar.empty + copied <- liftEffect EffectAVar.empty + resetDone <- liftEffect EffectAVar.empty + + liftEffect $ dispatch harness.runtime (RunSupersede (WaitBody taskWork (Right 1)) launched) + void $ await "source slot body" taskWork.started + awaitStatus "source slot active" Task.Active harness.updates + liftEffect $ dispatch harness.runtime (CopyTaskToOther copied) + void $ await "copy active into unused slot" copied + copiedView <- liftEffect $ Ref.read harness.tasks + Task.toStatus copiedView taskSlot `shouldEqual` Task.Active + Task.toStatus copiedView otherSlot `shouldEqual` Task.Idle + + liftEffect $ dispatch harness.runtime (ResetOther resetDone) + void $ await "reset copied inactive slot" resetDone + sourceSettled <- liftEffect $ EffectAVar.tryTake taskWork.settled + sourceSettled `shouldEqual` Nothing + + liftEffect $ dispatch harness.runtime (RunOther (WaitBody otherWork (Right 2)) launched) + void $ await "independent other slot" otherWork.started + awaitStatus "other slot active update" Task.Active harness.otherUpdates + sourceWhileOther <- liftEffect $ statusOf harness + otherWhileRunning <- liftEffect $ otherStatusOf harness + sourceWhileOther `shouldEqual` Task.Active + otherWhileRunning `shouldEqual` Task.Active + release otherWork + awaitStatus "other slot success" (Task.Succeeded 2) harness.otherUpdates + + liftEffect $ dispatch harness.runtime (CopyTaskToOther copied) + void $ await "copy active after other completion" copied + awaitStatus "copied completed slot becomes idle" Task.Idle harness.otherUpdates + sourceAfterCopy <- liftEffect $ statusOf harness + sourceAfterCopy `shouldEqual` Task.Active + + liftEffect $ dispatch harness.runtime (RunOther (WaitBody otherAgain (Right 3)) launched) + void $ await "other restart after copied state" otherAgain.started + awaitStatus "other restart active" Task.Active harness.otherUpdates + liftEffect $ dispatch harness.runtime (ResetOther resetDone) + void $ await "other reset after restart" resetDone + awaitStatus "other reset idle" Task.Idle harness.otherUpdates + sourceAfterOtherReset <- liftEffect $ statusOf harness + sourceAfterOtherReset `shouldEqual` Task.Active + sourceStillRunning <- liftEffect $ EffectAVar.tryTake taskWork.settled + sourceStillRunning `shouldEqual` Nothing + + release taskWork + awaitStatus "source slot completion" (Task.Succeeded 1) harness.updates + + it "rejects slot identity collisions before mutation or cancellation" do + errors <- liftEffect $ Ref.new [] + raised <- liftEffect EffectAVar.empty + harness <- makeHarness \context error -> do + let + prefix = case context of + ActionError _ -> "action: " + _ -> "wrong: " + Ref.modify_ (_ <> [ prefix <> Exception.message error ]) errors + void $ EffectAVar.tryPut unit raised + Aff.finally (liftEffect $ deactivate harness.runtime) do + authoritative <- liftEffect makeGate + sameBrandBody <- liftEffect makeGate + differentBrandBody <- liftEffect makeGate + launched <- liftEffect EffectAVar.empty + + liftEffect $ dispatch harness.runtime + (RunSupersede (WaitBody authoritative (Right 1)) launched) + void $ await "collision authoritative body" authoritative.started + awaitStatus "collision authoritative active" Task.Active harness.updates + callsBefore <- liftEffect $ Ref.read harness.setterCalls + + liftEffect $ dispatch harness.runtime + (RunSameBrandCollision (WaitBody sameBrandBody (Right 2))) + void $ await "same-brand collision" raised + shouldNotHaveStarted sameBrandBody + firstStillRunning <- liftEffect $ EffectAVar.tryTake authoritative.settled + firstStillRunning `shouldEqual` Nothing + + liftEffect $ dispatch harness.runtime + (RunDifferentBrandCollision (WaitBody differentBrandBody (Right 3))) + void $ await "different-brand collision" raised + shouldNotHaveStarted differentBrandBody + secondStillRunning <- liftEffect $ EffectAVar.tryTake authoritative.settled + secondStillRunning `shouldEqual` Nothing + status <- liftEffect $ statusOf harness + status `shouldEqual` Task.Active + callsAfter <- liftEffect $ Ref.read harness.setterCalls + callsAfter `shouldEqual` callsBefore + + actual <- liftEffect $ Ref.read errors + actual `shouldEqual` + [ "action: Halo task slot \"task\" is already bound to a different state focus" + , "action: Halo task slot \"alias\" overlaps state focus bound as \"task\"" + ] + release authoritative + awaitStatus "collision authority completion" (Task.Succeeded 1) harness.updates + + it "reset publishes Idle immediately and waits for finalizers" do + harness <- makeHarness \_ _ -> pure unit + Aff.finally (liftEffect $ deactivate harness.runtime) do + work <- liftEffect makeGate + finalizer <- liftEffect makeGate + externalWitness <- liftEffect $ Ref.new false + launched <- liftEffect EffectAVar.empty + resetDone <- liftEffect EffectAVar.empty + + liftEffect $ dispatch harness.runtime + (RunSupersede (CancellableBody work finalizer externalWitness) launched) + void $ await "resettable task launch" launched + void $ await "resettable task body" work.started + awaitStatus "resettable active" Task.Active harness.updates + + liftEffect $ dispatch harness.runtime (Reset resetDone) + awaitStatus "reset publishes idle" Task.Idle harness.updates + void $ await "reset finalizer start" finalizer.started + completionBeforeFinalizer <- liftEffect $ EffectAVar.tryTake resetDone + completionBeforeFinalizer `shouldEqual` Nothing + + release finalizer + void $ await "reset completion" resetDone + witness <- liftEffect $ Ref.read externalWitness + witness `shouldEqual` false + status <- liftEffect $ statusOf harness + status `shouldEqual` Task.Idle + + it "returns unexpected failures to Idle and routes ForkError" do + raised <- liftEffect EffectAVar.empty + errors <- liftEffect $ Ref.new [] + harness <- makeHarness \context error -> do + let + label = case context of + ForkError _ -> "fork" + _ -> "wrong context" + Ref.modify_ (_ <> [ label <> ": " <> Exception.message error ]) errors + void $ EffectAVar.tryPut unit raised + Aff.finally (liftEffect $ deactivate harness.runtime) do + gate <- liftEffect makeGate + launched <- liftEffect EffectAVar.empty + liftEffect $ dispatch harness.runtime (RunSupersede (UnexpectedBody gate) launched) + void $ await "unexpected task launch" launched + void $ await "unexpected task body" gate.started + awaitStatus "unexpected task active" Task.Active harness.updates + release gate + awaitStatus "unexpected task idle" Task.Idle harness.updates + void $ await "unexpected task onError" raised + actual <- liftEffect $ Ref.read errors + actual `shouldEqual` [ "fork: task boom" ] + + it "debounces with a private trailing timer and keeps only the latest result" do + harness <- makeHarness \_ _ -> pure unit + Aff.finally (liftEffect $ deactivate harness.runtime) do + firstTimer <- liftEffect makeTimer + secondTimer <- liftEffect makeTimer + firstBody <- liftEffect makeGate + secondBody <- liftEffect makeGate + launched <- liftEffect EffectAVar.empty + + liftEffect $ dispatch harness.runtime + (RunDebounce firstTimer (Milliseconds 50.0) (WaitBody firstBody (Right 1)) launched) + void $ await "first debounce launch" launched + void $ await "first debounce timer" firstTimer.gate.started + awaitStatus "first debounce active" Task.Active harness.updates + + liftEffect $ dispatch harness.runtime + (RunDebounce secondTimer (Milliseconds 50.0) (WaitBody secondBody (Right 2)) launched) + void $ await "second debounce timer" secondTimer.gate.started + void $ await "cancelled first debounce" firstTimer.gate.settled + active <- liftEffect $ statusOf harness + active `shouldEqual` Task.Active + shouldNotHaveStarted firstBody + + release secondTimer.gate + void $ await "latest debounced body" secondBody.started + release secondBody + awaitStatus "latest debounce success" (Task.Succeeded 2) harness.updates + shouldNotHaveStarted firstBody + + it "normalizes nonpositive debounce duration and reset cancels its timer" do + harness <- makeHarness \_ _ -> pure unit + Aff.finally (liftEffect $ deactivate harness.runtime) do + timer <- liftEffect makeTimer + body <- liftEffect makeGate + launched <- liftEffect EffectAVar.empty + resetDone <- liftEffect EffectAVar.empty + + liftEffect $ dispatch harness.runtime + (RunDebounce timer (Milliseconds (-10.0)) (WaitBody body (Right 1)) launched) + observed <- await "normalized debounce duration" timer.duration + observed `shouldEqual` Milliseconds 0.0 + void $ await "nonpositive debounce timer" timer.gate.started + awaitStatus "nonpositive debounce active" Task.Active harness.updates + shouldNotHaveStarted body + + liftEffect $ dispatch harness.runtime (Reset resetDone) + void $ await "debounce reset" resetDone + void $ await "debounce timer cancellation" timer.gate.settled + awaitStatus "debounce reset idle" Task.Idle harness.updates + shouldNotHaveStarted body + + it "publishes two-slot normalization before StrictMode onActivate work" do + firstTask <- liftEffect makeGate + firstOther <- liftEffect makeGate + nextTask <- liftEffect makeGate + nextOther <- liftEffect makeGate + taskGate <- liftEffect $ Ref.new firstTask + otherGate <- liftEffect $ Ref.new firstOther + snapshots <- liftEffect $ Ref.new [] + setterCalls <- liftEffect $ Ref.new 0 + let + activationHandlers = defaultHandlers + { onActivate = do + currentTask <- liftEffect $ Ref.read taskGate + currentOther <- liftEffect $ Ref.read otherGate + Task.once taskSlot do + liftAff $ waitForGate currentTask + pure (Right 1) + Task.once otherSlot do + liftAff $ waitForGate currentOther + pure (Right 2) + } + stateUpdate _ taskView = do + Ref.modify_ (_ + 1) setterCalls + Ref.modify_ + ( _ <> + [ Tuple + (Task.toStatus taskView taskSlot) + (Task.toStatus taskView otherSlot) + ] + ) + snapshots + runtime <- liftEffect $ createRuntime identity + { initialProps: unit + , initialState + , spec: { handlers: activationHandlers, onError: \_ _ -> pure unit } + , stateUpdate + } + + liftEffect $ activate runtime + void $ await "first StrictMode task" firstTask.started + void $ await "first StrictMode other" firstOther.started + beforeCleanup <- liftEffect $ Ref.read snapshots + beforeCleanup `shouldEqual` + [ Tuple Task.Active Task.Idle + , Tuple Task.Active Task.Active + ] + callsBeforeCleanup <- liftEffect $ Ref.read setterCalls + + liftEffect $ deactivate runtime + void $ await "first StrictMode task cancellation" firstTask.settled + void $ await "first StrictMode other cancellation" firstOther.settled + callsAfterCleanup <- liftEffect $ Ref.read setterCalls + callsAfterCleanup `shouldEqual` callsBeforeCleanup + + liftEffect do + Ref.write nextTask taskGate + Ref.write nextOther otherGate + activate runtime + void $ await "replayed StrictMode task" nextTask.started + void $ await "replayed StrictMode other" nextOther.started + afterReplay <- liftEffect $ Ref.read snapshots + afterReplay `shouldEqual` + [ Tuple Task.Active Task.Idle + , Tuple Task.Active Task.Active + , Tuple Task.Idle Task.Idle + , Tuple Task.Active Task.Idle + , Tuple Task.Active Task.Active + ] + liftEffect $ deactivate runtime + + it "normalizes active state without a cleanup setter and republishes before reactivation work" do + harness <- makeHarness \_ _ -> pure unit + first <- liftEffect makeGate + other <- liftEffect makeGate + second <- liftEffect makeGate + launched <- liftEffect EffectAVar.empty + + liftEffect $ dispatch harness.runtime (RunOnce (WaitBody first (Right 1)) launched) + void $ await "pre-deactivation task" first.started + awaitStatus "pre-deactivation active" Task.Active harness.updates + liftEffect $ dispatch harness.runtime (RunOther (WaitBody other (Right 9)) launched) + void $ await "pre-deactivation other task" other.started + awaitStatus "pre-deactivation other active" Task.Active harness.otherUpdates + callsBefore <- liftEffect $ Ref.read harness.setterCalls + + liftEffect $ deactivate harness.runtime + void $ await "deactivated task cancellation" first.settled + void $ await "deactivated other cancellation" other.settled + callsAfterCleanup <- liftEffect $ Ref.read harness.setterCalls + callsAfterCleanup `shouldEqual` callsBefore + + liftEffect $ activate harness.runtime + awaitStatus "reactivation idle publication" Task.Idle harness.updates + awaitStatus "reactivation other idle publication" Task.Idle harness.otherUpdates + liftEffect $ dispatch harness.runtime (RunOnce (WaitBody second (Right 2)) launched) + void $ await "reactivated once task" second.started + awaitStatus "reactivated task active" Task.Active harness.updates + release second + awaitStatus "reactivated task success" (Task.Succeeded 2) harness.updates + + ignored <- liftEffect makeGate + liftEffect do + deactivate harness.runtime + activate harness.runtime + dispatch harness.runtime (RunOnce (WaitBody ignored (Right 3)) launched) + shouldNotHaveStarted ignored + terminal <- liftEffect $ statusOf harness + terminal `shouldEqual` Task.Succeeded 2 + liftEffect $ deactivate harness.runtime + + it "projects a cross-runtime active snapshot Idle on first render" do + source <- makeHarness \_ _ -> pure unit + sourceWork <- liftEffect makeGate + launched <- liftEffect EffectAVar.empty + liftEffect $ dispatch source.runtime (RunSupersede (WaitBody sourceWork (Right 1)) launched) + void $ await "cross-runtime source body" sourceWork.started + awaitStatus "cross-runtime source active" Task.Active source.updates + foreignState <- liftEffect $ Ref.read source.state + + let firstView = TaskTypes.emptyView foreignState + Task.toStatus firstView taskSlot `shouldEqual` Task.Idle + targetState <- liftEffect $ Ref.new foreignState + targetTasks <- liftEffect $ Ref.new firstView + target <- liftEffect $ createRuntime identity + { initialProps: unit + , initialState: foreignState + , spec: { handlers, onError: \_ _ -> pure unit } + , stateUpdate: \state tasks -> do + Ref.write state targetState + Ref.write tasks targetTasks + } + targetWork <- liftEffect makeGate + Aff.finally + ( liftEffect do + deactivate target + deactivate source.runtime + ) + do + liftEffect do + activate target + dispatch target (RunOnce (WaitBody targetWork (Right 2)) launched) + void $ await "cross-runtime target body" targetWork.started + sourceSettled <- liftEffect $ EffectAVar.tryTake sourceWork.settled + sourceSettled `shouldEqual` Nothing + currentTargetTasks <- liftEffect $ Ref.read targetTasks + Task.toStatus currentTargetTasks taskSlot `shouldEqual` Task.Active + release targetWork + release sourceWork + + it "uses the latest state setter for managed completion" do + harness <- makeHarness \_ _ -> pure unit + Aff.finally (liftEffect $ deactivate harness.runtime) do + gate <- liftEffect makeGate + launched <- liftEffect EffectAVar.empty + newState <- liftEffect $ Ref.new initialState + newTasks <- liftEffect $ Ref.new (TaskTypes.emptyView initialState) + liftEffect $ dispatch harness.runtime (RunSupersede (WaitBody gate (Right 7)) launched) + void $ await "setter task body" gate.started + awaitStatus "setter task active" Task.Active harness.updates + + liftEffect $ syncSpec harness.runtime identity + { spec: { handlers, onError: \_ _ -> pure unit } + , stateUpdate: \next tasks -> do + Ref.write next newState + Ref.write tasks newTasks + } + release gate + void $ await "setter task settlement" gate.settled + currentTasks <- liftEffect $ Ref.read newTasks + Task.toStatus currentTasks taskSlot `shouldEqual` Task.Succeeded 7 + oldTasks <- liftEffect $ Ref.read harness.tasks + Task.toStatus oldTasks taskSlot `shouldEqual` Task.Active + + snapshotSpec + +newtype AppM a = AppM (ReaderT Int Aff a) + +derive newtype instance functorAppM :: Functor AppM +derive newtype instance applyAppM :: Apply AppM +derive newtype instance applicativeAppM :: Applicative AppM +derive newtype instance bindAppM :: Bind AppM +derive newtype instance monadAppM :: Monad AppM + +runAppM :: Int -> AppM ~> Aff +runAppM environment (AppM computation) = runReaderT computation environment + +readEnvironment :: AppM Int +readEnvironment = AppM ask + +type SnapshotState = { task :: Task.State String Int } + +snapshotSlot :: Task.Slot "task" SnapshotState String Int +snapshotSlot = Task.slot (Proxy :: Proxy "task") + +data SnapshotAction = LaunchSnapshot Gate Gate (AVar Int) + +snapshotHandlers :: Handlers Unit SnapshotState SnapshotAction AppM +snapshotHandlers = defaultHandlers + { onAction = \(LaunchSnapshot handlerGate bodyGate result) -> do + lift $ AppM $ lift $ waitForGate handlerGate + Task.supersede snapshotSlot do + lift $ AppM $ lift $ waitForGate bodyGate + environment <- lift readEnvironment + lift $ AppM $ lift $ void $ AVar.tryPut environment result + pure (Right environment) + } + +snapshotSpec :: Spec Unit +snapshotSpec = describe "managed task interpreter snapshots" do + it "inherits the launching handler's interpreter" do + handlerGate <- liftEffect makeGate + bodyGate <- liftEffect makeGate + result <- liftEffect EffectAVar.empty + runtime <- liftEffect $ createRuntime (runAppM 1) + { initialProps: unit + , initialState: { task: Task.idle snapshotSlot } + , spec: { handlers: snapshotHandlers, onError: \_ _ -> pure unit } + , stateUpdate: \_ _ -> pure unit + } + Aff.finally (liftEffect $ deactivate runtime) do + liftEffect do + activate runtime + dispatch runtime (LaunchSnapshot handlerGate bodyGate result) + void $ await "snapshot handler" handlerGate.started + liftEffect $ syncSpec runtime (runAppM 2) + { spec: { handlers: snapshotHandlers, onError: \_ _ -> pure unit } + , stateUpdate: \_ _ -> pure unit + } + release handlerGate + void $ await "snapshot task body" bodyGate.started + release bodyGate + actual <- await "snapshot task environment" result + actual `shouldEqual` 1