Modular, context-aware and aspect-oriented dendritic Nix configurations. Discussions: https://oeiuwq.zulipchat.com/join/nqp26cd4kngon6mo3ncgnuap/ den.oeiuwq.com
configurations den dendritic nix aspect oriented

den.ctx. Den declarative context definitions. (#175)

Related #174

# Declarative Context Definitions

This introduces [`den.ctx`](https://github.com/vic/den/pull/175), a
declarative system for defining how context (data) is transformed and
which aspects are applied at every stage of the configuration pipeline.

## The Problem

Before this release, `den.default` served two purposes:

- A place to define global or generic includes for `host`, `user`, and
`home` entities.
- The backbone of context propagation — moving data from `{ host }` to
`{ host, user }` to `{ host, user }` in the HM pipeline, etc.

As a consequence, `den.default.includes` was abused by many of us,
including Den itself, because it was [where context transformation
happened](https://github.com/vic/den/blob/f8cb8c618e1680e99c165d2bf826600170abb5a2/modules/aspects/dependencies.nix#L28)
[\[2\]](https://github.com/vic/den/blob/f8cb8c618e1680e99c165d2bf826600170abb5a2/modules/aspects/provides/home-manager/hm-dependencies.nix#L31).
This "dependency system" — parametric aspects installed unconditionally
at `den.default.includes` — was hard to reason about, hard to document,
and hard for people to understand.

The symptoms were duplicate configuration values, caused by lax
parametric functions matching too many pipeline stages.

## What den.ctx Provides

- **Keep `den.default` for what it's good at**: global settings. You can
still use `den.default.includes`, but there are better alternatives now.
- **Move the dependency system out of `den.default.includes`**: those
parametric aspects were not individually testable, and you couldn't
change how data flows. They were Den's hardcoded backbone.
- **Declarative data stages**: context transformations are now explicit.
Given a `host`, you declare how to enumerate users, detect HM support,
etc.
- **Named contexts**: previously we identified contexts only by their
`attrNames` — `{ host }`, `{ host, user }`. Now they have names:
`ctx.host`, `ctx.hm-host`. Names allow different contexts with the same
structural shape but different semantic guarantees.
- **Extensible context flows**: one core principle of Den is not getting
in your way. You can create alternative flows, or use Den purely as a
library.

## Named Contexts: Transform, Don't Validate

Named contexts carry semantic meaning beyond their structure. `ctx.host
{ host }` and `ctx.hm-host { host }` hold the same data, but `hm-host`
**guarantees** that home-manager support was validated:

- `inputs.home-manager` exists (or the host has a custom `hm-module`)
- The host has at least one user with `class = "homeManager"`

You cannot obtain an `hm-host` context unless these conditions hold.
This follows the transform-don't-validate principle.

## How a Context Type Works

A context type has four components: `desc`, `conf`, `includes`, and
`into`.

```nix
den.ctx.foo.desc = "The foo context requires { foo } data.";

den.ctx.foo.conf = { foo }: my-aspects.${foo.name};
```

When `ctx.foo` is applied — it works like a function taking `{ foo }` —
it locates the responsible aspect via `conf`. For example, `ctx.foo {
foo.name = "bar"; }` uses `my-aspects.bar`. The aspect's owned config,
static includes, and parametric includes matching `{ foo }` all
contribute to whatever `ctx.foo` is being used to configure.

Context types are independent of NixOS. Den can be used as a library for
network topologies, declarative cloud infrastructure, or anything
describable as data transformations.

## How a NixOS Configuration Is Built

The initial data for `nixosConfigurations.igloo` is the host itself:

```nix
# Nothing NixOS-specific yet — just a graph of dependencies.
aspect = den.ctx.host {
host = den.hosts.x86_64-linux.igloo;
};
```

The result of `ctxApply` is a new aspect that includes
`den.aspects.igloo` plus the entire transformation chain — user
enumeration, HM detection, defaults.

```nix
# This is where things enter the NixOS domain.
nixosModule = aspect.resolve { class = "nixos"; };

nixosConfigurations.igloo = lib.nixosSystem {
modules = [ nixosModule ];
};
```

These two steps can be adapted for any class, for anything
Nix-configurable.

## Context Propagation

Context transformation is declarative. If your data fans out to other
contexts, you specify the transformations using `.into`:

```nix
den.ctx.foo.conf = { foo }: ...;
den.ctx.moo.conf = { moo }: ...;

den.ctx.foo.into.moo = { foo }: lib.singleton { moo = deriveMoo foo; };
```

All `<source>.into.<target>` transformations are taken into account by
`ctxApply`.

### Why Lists?

Transformations have the type `source → [ target ]`. This enables:

- **Fan-out**: one host produces many `{ host, user }` contexts (`map`)
- **Conditional propagation**: zero or one contexts (`lib.optional`)
- **Pass-through**: identity transformation (`lib.singleton`)

For example, HM detection uses conditional propagation:

```nix
den.ctx.host.into.hm-host = { host }:
lib.optional (isHmSupported host) { inherit host; };
```

Same data, but the named context guarantees validation passed.

## Contexts as Aspect Cutting-Points

Contexts are aspect-like themselves. They have owned configs and
`.includes`:

```nix
# Owned config — only for validated HM hosts:
den.ctx.hm-host.nixos.home-manager.useGlobalPkgs = true;

# Scoped includes — only for validated HM hosts:
den.ctx.hm-host.includes = [
({ host, ... }: { nixos.home-manager.backupFileExtension = "bak"; })
];
```

This is like `den.default.includes` **but scoped** — it only activates
for hosts with validated home-manager support.

## Extending the Context Flow

You can add new transformations to any existing context type:

```nix
den.ctx.hm-host.into.foo = { host }: [ { foo = host.name; } ];
den.ctx.foo.conf = { foo }: ...;
den.ctx.foo.includes = [ ({ foo, ... }: ...) ];
```

The module system merges these definitions. You can extend the pipeline
without modifying any built-in file.

## Custom Context Flows

Each host has a `mainModule` option that defaults to:

```nix
(den.ctx.host { host }).resolve { class = "nixos"; }
```

You can override `mainModule` to use a completely alternative context
flow, independent of `ctx.host`. Custom flows can be designed and tested
in isolation — Den's CI uses a `funny.names` class that has nothing to
do with NixOS to verify context mechanics independently.

## What Happened to den.default?

`den.default` stays and is still useful for truly global settings. The
issue was abusing `den.default.includes` as the context propagation
backbone.

### Internal Changes

Previously, all host, user, and home aspects had:

```nix
includes = [ den.default ]
```

Now they **no longer include `den.default` directly**. Including
`den.default` explicitly is discouraged.

### How Defaults Are Applied Now

Each context type transforms into `default`:

```nix
den.ctx.host.into.default = lib.singleton; # passes { host }
den.ctx.user.into.default = lib.singleton; # passes { host, user }
den.ctx.home.into.default = lib.singleton; # passes { home }
```

`den.default` is now an alias for `den.ctx.default`. The data that flows
into `den.default.includes` comes from these declarative
transformations, not from direct aspect inclusion.

### Best Practices

| Instead of | Use |
|-----------|-----|
| `den.default.includes = [ hostFunc ]` | `den.ctx.host.includes = [
hostFunc ]` |
| `den.default.includes = [ hmFunc ]` | `den.ctx.hm-host.includes = [
hmFunc ]` |
| `den.default.nixos.x = 1` | `den.ctx.host.nixos.x = 1` |

`den.default` remains the right place for values that genuinely apply
everywhere — like `stateVersion`. Use context-specific includes for
anything that belongs to a particular pipeline stage.

authored by oeiuwq.com and committed by

GitHub def3ecfb f8cb8c61

+11420 -2028
+14 -13
.github/workflows/gh-pages.yml
··· 1 1 name: GH Pages 2 2 on: 3 - gollum: 4 3 workflow_dispatch: 4 + push: 5 + branches: [main] 6 + paths: ["docs/**"] 5 7 permissions: 6 8 contents: read 7 9 pages: write ··· 16 18 url: ${{ steps.deployment.outputs.page_url }} 17 19 runs-on: ubuntu-latest 18 20 steps: 19 - - name: Install mdbook 21 + - uses: wimpysworld/nothing-but-nix@main 22 + - uses: cachix/install-nix-action@v31 23 + - uses: DeterminateSystems/magic-nix-cache-action@v13 24 + - uses: actions/checkout@v4 25 + - name: Build 20 26 run: | 21 - set -ve -o pipefail 22 - curl -vL https://github.com/rust-lang/mdBook/releases/download/v0.4.52/mdbook-v0.4.52-x86_64-unknown-linux-gnu.tar.gz -o mdbook.tar.gz 23 - sudo tar xf mdbook.tar.gz -C /usr/local/bin mdbook 24 - mdbook --version 25 - - name: Checkout 26 - uses: actions/checkout@v4 27 - with: 28 - repository: "${{github.repository}}.wiki" 29 - - name: Build 30 - run: mdbook build 27 + pushd docs 28 + nix profile install nixpkgs#nodejs nixpkgs#pnpm 29 + pnpm install 30 + pnpm run build 31 + popd 31 32 - name: Setup Pages 32 33 uses: actions/configure-pages@v5 33 34 - name: Upload artifact 34 35 uses: actions/upload-pages-artifact@v3 35 36 with: 36 - path: "./book" 37 + path: "./docs/build" 37 38 - name: Deploy to GitHub Pages 38 39 id: deployment 39 40 uses: actions/deploy-pages@v4
+21 -1
.github/workflows/test.yml
··· 70 70 EOF 71 71 git add templates/bogus/modules/ci-runtime.nix 72 72 - run: nix flake check ./templates/bogus --override-input den github:$GITHUB_REPOSITORY/$GITHUB_SHA 73 + tests: 74 + needs: [non-draft] 75 + name: tests 76 + runs-on: ubuntu-latest 77 + steps: 78 + - uses: wimpysworld/nothing-but-nix@main 79 + - uses: cachix/install-nix-action@v31 80 + - uses: DeterminateSystems/magic-nix-cache-action@v13 81 + - run: nix flake init -t github:$GITHUB_REPOSITORY/$GITHUB_SHA#ci 82 + - run: sed -i "s@\"github:vic/den\"@\"github:vic/den/$GITHUB_SHA\"@" flake.nix 83 + - run: | 84 + cat <<-EOF > modules/ci-runtime.nix 85 + { lib, ... }: 86 + { 87 + _module.args.CI = true; 88 + } 89 + EOF 90 + - run: nix flake update den 91 + - run: nix flake metadata 92 + - run: nix flake check 73 93 template: 74 94 needs: [non-draft] 75 95 strategy: 76 96 matrix: 77 97 os: [ubuntu-latest, macos-latest] 78 - template: [default, ci, example] 98 + template: [default, example] 79 99 name: Check template ${{matrix.template}} ${{matrix.os}} 80 100 runs-on: ${{matrix.os}} 81 101 steps:
+22 -13
README.md
··· 9 9 <img src="https://github.com/vic/den/actions/workflows/test.yml/badge.svg" alt="CI Status"/> </a> 10 10 </p> 11 11 12 - # den - Re-usable Dendritic Nix configurations. [See MOTIVATION](https://den.oeiuwq.com/motivation.html) 12 + # den - Re-usable Dendritic Nix configurations. [See MOTIVATION](https://den.oeiuwq.com/motivation/) 13 13 14 14 > den and [vic](https://bsky.app/profile/oeiuwq.bsky.social)'s [dendritic libs](https://vic.github.io/dendrix/Dendritic-Ecosystem.html#vics-dendritic-libraries) made for you with Love++ and AI--. If you like my work, consider [sponsoring](https://github.com/sponsors/vic) 15 15 ··· 20 20 21 21 <img width="300" height="300" alt="den" src="https://github.com/user-attachments/assets/af9c9bca-ab8b-4682-8678-31a70d510bbb" /> 22 22 23 - - [Dendritic](https://github.com/mightyiam/dendritic): **same** concern across **different** Nix classes. 23 + - [Dendritic](https://den.oeiuwq.com/explanation/core-principles/): **same** concern across **different** Nix classes. 24 24 25 - - [Flake optional](templates/noflake). Works with _stable_/_unstable_ Nix and with/without flake-parts. 25 + - [Flake optional](https://den.oeiuwq.com/guides/no-flakes/). Works with _stable_/_unstable_ Nix and with/without flake-parts. 26 26 27 27 - Create [DRY](modules/aspects/provides/unfree/unfree.nix) & [`class`-generic](modules/aspects/provides/primary-user.nix) modules. 28 28 29 - - [Parametric](modules/aspects/provides/define-user.nix) over `host`/`home`/`user`. 29 + - [Parametric](https://den.oeiuwq.com/explanation/parametric/) over `host`/`home`/`user`. 30 30 31 - - Context-aware [dependencies](modules/aspects/dependencies.nix) with `host<->user` bidirectional contributions. 31 + - Context-aware [dependencies](https://den.oeiuwq.com/explanation/context-system/) with `host<->user` [bidirectional](https://den.oeiuwq.com/guides/bidirectional/) contributions. 32 32 33 - - [Share](templates/example/modules/namespace.nix) aspects across systems & repos. 33 + - [Share](https://den.oeiuwq.com/guides/namespaces/) aspects across systems & repos. 34 34 35 35 - [Routable](templates/example/modules/aspects/eg/routes.nix) configurations. 36 36 ··· 38 38 39 39 - Use different `stable`/`unstable` input channels per host. 40 40 41 - - Freeform `host`/`user`/`home` [schemas](modules/_types.nix) (no `specialArgs`) with [base](https://github.com/vic/den/pull/119) modules. 41 + - Freeform `host`/`user`/`home` [schemas](https://den.oeiuwq.com/reference/schema/) (no `specialArgs`) with [base](https://github.com/vic/den/pull/119) modules. 42 42 43 43 - Multi-platform, multi-tenant hosts. 44 44 45 - - [Batteries](modules/aspects/provides/): Opt-in, replaceable aspects. 45 + - [Batteries](https://den.oeiuwq.com/guides/batteries/): Opt-in, replaceable aspects. 46 46 47 - - Opt-in [`<angle/brackets>`](https://vic.github.io/den/angle-brackets.html) aspect resolution. 47 + - Opt-in [`<angle/brackets>`](https://den.oeiuwq.com/guides/angle-brackets/) aspect resolution. 48 48 49 - - _Incremental_ adoption on [exising](https://github.com/vic/den/discussions/151#discussioncomment-15797741) flakes, and _unobstrusive_ [migration](https://vic.github.io/den/migration.html) plan. 49 + - _Incremental_ adoption on [exising](https://github.com/vic/den/discussions/151#discussioncomment-15797741) flakes, and _unobstrusive_ [migration](https://den.oeiuwq.com/guides/migrate/) plan. 50 50 51 51 - Features [tested](templates/ci). 52 52 53 - - REPL [friendly](https://github.com/vic/den/blob/f5c44098e4855e07bf5cbcec00509e75ddde4220/templates/bogus/modules/bug.nix#L34) [debugging](https://den.oeiuwq.com/debugging.html). 53 + - REPL [friendly](https://github.com/vic/den/blob/f5c44098e4855e07bf5cbcec00509e75ddde4220/templates/bogus/modules/bug.nix#L34) [debugging](https://den.oeiuwq.com/guides/debug/). 54 54 55 55 Need more **batteries**? See [vic/denful](https://github.com/vic/denful). 56 56 ··· 92 92 ### Den fundamental idea 93 93 94 94 > Configurations that can be applied to multiple host/user combinations. 95 - > The [`__functor`](https://den.oeiuwq.com/functor.html) pattern makes aspects parametric. 95 + > The [`__functor`](https://den.oeiuwq.com/explanation/aspects/) pattern makes aspects parametric. 96 96 97 97 <details> 98 98 ··· 146 146 147 147 </details> 148 148 149 + ### Library vs framework 150 + 151 + Den works as both a **library** and a **framework**: 152 + 153 + - **Library** — a domain‑agnostic, context‑aware, aspect‑oriented API you can import and extend; build custom context pipelines and parametric aspects for anything Nix configurable. 154 + - **Framework** — batteries, ready-made schemas (`host`/`user`/`home`) and integrations tailored for NixOS/Darwin/home-manager configurations. 155 + 156 + Den is independent and extensible — you can use only the library pieces, or adopt the framework batteries for faster NixOS/Darwin setups. See the full explanation: https://den.oeiuwq.com/explanation/library-vs-framework/ 157 + 149 158 ### Code example 150 159 151 160 Schema based hosts/users/homes entities (see [`_types.nix`](modules/_types.nix)). ··· 240 249 241 250 Feel free to to **explore** the codebase, particularly our [included batteries](modules/aspects/provides) and [tests](templates/ci). 242 251 243 - ## Learn more at our [documentation website](https://vic.github.io/den) 252 + ## Learn more at our [documentation website](https://den.oeiuwq.com) 244 253 245 254 Join our [community discussion](https://github.com/vic/den/discussions).
+6 -1
checkmate/modules/formatter.nix
··· 1 1 { 2 - perSystem.treefmt.settings.global.excludes = [ ".github/*TEMPLATE*/*" ]; 2 + perSystem.treefmt.settings.global.excludes = [ 3 + ".github/*TEMPLATE*/*" 4 + "docs/*" 5 + ]; 6 + perSystem.treefmt.programs.deadnix.enable = false; 7 + perSystem.treefmt.programs.nixf-diagnose.enable = false; 3 8 }
+21
docs/.gitignore
··· 1 + # build output 2 + dist/ 3 + # generated types 4 + .astro/ 5 + 6 + # dependencies 7 + node_modules/ 8 + 9 + # logs 10 + npm-debug.log* 11 + yarn-debug.log* 12 + yarn-error.log* 13 + pnpm-debug.log* 14 + 15 + 16 + # environment variables 17 + .env 18 + .env.production 19 + 20 + # macOS-specific files 21 + .DS_Store
+4
docs/.vscode/extensions.json
··· 1 + { 2 + "recommendations": ["astro-build.astro-vscode"], 3 + "unwantedRecommendations": [] 4 + }
+11
docs/.vscode/launch.json
··· 1 + { 2 + "version": "0.2.0", 3 + "configurations": [ 4 + { 5 + "command": "./node_modules/.bin/astro dev", 6 + "name": "Development server", 7 + "request": "launch", 8 + "type": "node-terminal" 9 + } 10 + ] 11 + }
+49
docs/README.md
··· 1 + # Starlight Starter Kit: Basics 2 + 3 + [![Built with Starlight](https://astro.badg.es/v2/built-with-starlight/tiny.svg)](https://starlight.astro.build) 4 + 5 + ``` 6 + pnpm create astro@latest -- --template starlight 7 + ``` 8 + 9 + > 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun! 10 + 11 + ## 🚀 Project Structure 12 + 13 + Inside of your Astro + Starlight project, you'll see the following folders and files: 14 + 15 + ``` 16 + . 17 + ├── public/ 18 + ├── src/ 19 + │ ├── assets/ 20 + │ ├── content/ 21 + │ │ └── docs/ 22 + │ └── content.config.ts 23 + ├── astro.config.mjs 24 + ├── package.json 25 + └── tsconfig.json 26 + ``` 27 + 28 + Starlight looks for `.md` or `.mdx` files in the `src/content/docs/` directory. Each file is exposed as a route based on its file name. 29 + 30 + Images can be added to `src/assets/` and embedded in Markdown with a relative link. 31 + 32 + Static assets, like favicons, can be placed in the `public/` directory. 33 + 34 + ## 🧞 Commands 35 + 36 + All commands are run from the root of the project, from a terminal: 37 + 38 + | Command | Action | 39 + | :------------------------ | :----------------------------------------------- | 40 + | `pnpm install` | Installs dependencies | 41 + | `pnpm dev` | Starts local dev server at `localhost:4321` | 42 + | `pnpm build` | Build your production site to `./dist/` | 43 + | `pnpm preview` | Preview your build locally, before deploying | 44 + | `pnpm astro ...` | Run CLI commands like `astro add`, `astro check` | 45 + | `pnpm astro -- --help` | Get help using the Astro CLI | 46 + 47 + ## 👀 Want to learn more? 48 + 49 + Check out [Starlight’s docs](https://starlight.astro.build/), read [the Astro documentation](https://docs.astro.build), or jump into the [Astro Discord server](https://astro.build/chat).
+84
docs/astro.config.mjs
··· 1 + // @ts-check 2 + import { defineConfig, fontProviders } from 'astro/config'; 3 + import starlight from '@astrojs/starlight'; 4 + 5 + import mermaid from 'astro-mermaid'; 6 + import catppuccin from "@catppuccin/starlight"; 7 + 8 + // https://astro.build/config 9 + export default defineConfig({ 10 + experimental: { 11 + fonts: [ 12 + { 13 + provider: fontProviders.google(), 14 + name: "Victor Mono", 15 + cssVariable: "--font-victor-mono", 16 + }, 17 + ], 18 + }, 19 + integrations: [ 20 + mermaid({ 21 + theme: 'forest', 22 + autoTheme: true 23 + }), 24 + starlight({ 25 + title: 'den', 26 + social: [{ icon: 'github', label: 'GitHub', href: 'https://github.com/vic/den' }], 27 + sidebar: [ 28 + { label: 'Motivation', slug: 'motivation' }, 29 + { 30 + label: 'Learn', 31 + items: [ 32 + { label: 'Core Principles', slug: 'explanation/core-principles' }, 33 + { label: 'Context System', slug: 'explanation/context-system' }, 34 + { label: 'Aspects & Functors', slug: 'explanation/aspects' }, 35 + { label: 'Parametric Aspects', slug: 'explanation/parametric' }, 36 + { label: 'Context Pipeline', slug: 'explanation/context-pipeline' }, 37 + { label: 'Library vs Framework', slug: 'explanation/library-vs-framework' }, 38 + ], 39 + }, 40 + { 41 + label: 'Adopt', 42 + items: [ 43 + { label: 'Getting Started', slug: 'tutorials/getting-started' }, 44 + { label: 'Your First Aspect', slug: 'tutorials/first-aspect' }, 45 + { label: 'Context-Aware Configs', slug: 'tutorials/context-aware' }, 46 + ], 47 + }, 48 + { 49 + label: 'How-To Guides', 50 + items: [ 51 + { label: 'Declare Hosts & Users', slug: 'guides/declare-hosts' }, 52 + { label: 'Bidirectional Dependencies', slug: 'guides/bidirectional' }, 53 + { label: 'Home-Manager Integration', slug: 'guides/home-manager' }, 54 + { label: 'Use Batteries', slug: 'guides/batteries' }, 55 + { label: 'Share with Namespaces', slug: 'guides/namespaces' }, 56 + { label: 'Angle Brackets Syntax', slug: 'guides/angle-brackets' }, 57 + { label: 'Custom Nix Classes', slug: 'guides/custom-classes' }, 58 + { label: 'Use Without Flakes', slug: 'guides/no-flakes' }, 59 + { label: 'Migrate to Den', slug: 'guides/migrate' }, 60 + { label: 'Debug Configurations', slug: 'guides/debug' }, 61 + ], 62 + }, 63 + { 64 + label: 'Reference', 65 + items: [ 66 + { label: 'den.ctx', slug: 'reference/ctx' }, 67 + { label: 'den.lib', slug: 'reference/lib' }, 68 + { label: 'den.aspects', slug: 'reference/aspects' }, 69 + { label: 'Entity Schema', slug: 'reference/schema' }, 70 + { label: 'Batteries', slug: 'reference/batteries' }, 71 + { label: 'Configuration Output', slug: 'reference/output' }, 72 + ], 73 + }, 74 + { label: 'Community', slug: 'community' }, 75 + ], 76 + plugins: [ 77 + catppuccin({ 78 + dark: { flavor: "macchiato", accent: "mauve" }, 79 + light: { flavor: "latte", accent: "mauve" }, 80 + }), 81 + ], 82 + }), 83 + ], 84 + });
+20
docs/package.json
··· 1 + { 2 + "name": "den", 3 + "type": "module", 4 + "version": "0.0.1", 5 + "scripts": { 6 + "dev": "astro dev", 7 + "start": "astro dev", 8 + "build": "astro build", 9 + "preview": "astro preview", 10 + "astro": "astro" 11 + }, 12 + "dependencies": { 13 + "@astrojs/starlight": "^0.37.6", 14 + "@catppuccin/starlight": "^1.1.1", 15 + "astro": "^5.17.3", 16 + "astro-mermaid": "^1.3.1", 17 + "mermaid": "^11.12.3", 18 + "sharp": "^0.34.5" 19 + } 20 + }
+5307
docs/pnpm-lock.yaml
··· 1 + lockfileVersion: '9.0' 2 + 3 + settings: 4 + autoInstallPeers: true 5 + excludeLinksFromLockfile: false 6 + 7 + importers: 8 + 9 + .: 10 + dependencies: 11 + '@astrojs/starlight': 12 + specifier: ^0.37.6 13 + version: 0.37.6(astro@5.17.3(rollup@4.57.1)(typescript@5.9.3)) 14 + '@catppuccin/starlight': 15 + specifier: ^1.1.1 16 + version: 1.1.1(@astrojs/starlight@0.37.6(astro@5.17.3(rollup@4.57.1)(typescript@5.9.3)))(astro@5.17.3(rollup@4.57.1)(typescript@5.9.3)) 17 + astro: 18 + specifier: ^5.17.3 19 + version: 5.17.3(rollup@4.57.1)(typescript@5.9.3) 20 + astro-mermaid: 21 + specifier: ^1.3.1 22 + version: 1.3.1(astro@5.17.3(rollup@4.57.1)(typescript@5.9.3))(mermaid@11.12.3) 23 + mermaid: 24 + specifier: ^11.12.3 25 + version: 11.12.3 26 + sharp: 27 + specifier: ^0.34.5 28 + version: 0.34.5 29 + 30 + packages: 31 + 32 + '@antfu/install-pkg@1.1.0': 33 + resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==} 34 + 35 + '@astrojs/compiler@2.13.1': 36 + resolution: {integrity: sha512-f3FN83d2G/v32ipNClRKgYv30onQlMZX1vCeZMjPsMMPl1mDpmbl0+N5BYo4S/ofzqJyS5hvwacEo0CCVDn/Qg==} 37 + 38 + '@astrojs/internal-helpers@0.7.5': 39 + resolution: {integrity: sha512-vreGnYSSKhAjFJCWAwe/CNhONvoc5lokxtRoZims+0wa3KbHBdPHSSthJsKxPd8d/aic6lWKpRTYGY/hsgK6EA==} 40 + 41 + '@astrojs/markdown-remark@6.3.10': 42 + resolution: {integrity: sha512-kk4HeYR6AcnzC4QV8iSlOfh+N8TZ3MEStxPyenyCtemqn8IpEATBFMTJcfrNW32dgpt6MY3oCkMM/Tv3/I4G3A==} 43 + 44 + '@astrojs/mdx@4.3.13': 45 + resolution: {integrity: sha512-IHDHVKz0JfKBy3//52JSiyWv089b7GVSChIXLrlUOoTLWowG3wr2/8hkaEgEyd/vysvNQvGk+QhysXpJW5ve6Q==} 46 + engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0} 47 + peerDependencies: 48 + astro: ^5.0.0 49 + 50 + '@astrojs/prism@3.3.0': 51 + resolution: {integrity: sha512-q8VwfU/fDZNoDOf+r7jUnMC2//H2l0TuQ6FkGJL8vD8nw/q5KiL3DS1KKBI3QhI9UQhpJ5dc7AtqfbXWuOgLCQ==} 52 + engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0} 53 + 54 + '@astrojs/sitemap@3.7.0': 55 + resolution: {integrity: sha512-+qxjUrz6Jcgh+D5VE1gKUJTA3pSthuPHe6Ao5JCxok794Lewx8hBFaWHtOnN0ntb2lfOf7gvOi9TefUswQ/ZVA==} 56 + 57 + '@astrojs/starlight@0.37.6': 58 + resolution: {integrity: sha512-wQrKwH431q+8FsLBnNQeG+R36TMtEGxTQ2AuiVpcx9APcazvL3n7wVW8mMmYyxX0POjTnxlcWPkdMGR3Yj1L+w==} 59 + peerDependencies: 60 + astro: ^5.5.0 61 + 62 + '@astrojs/telemetry@3.3.0': 63 + resolution: {integrity: sha512-UFBgfeldP06qu6khs/yY+q1cDAaArM2/7AEIqQ9Cuvf7B1hNLq0xDrZkct+QoIGyjq56y8IaE2I3CTvG99mlhQ==} 64 + engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0} 65 + 66 + '@babel/helper-string-parser@7.27.1': 67 + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} 68 + engines: {node: '>=6.9.0'} 69 + 70 + '@babel/helper-validator-identifier@7.28.5': 71 + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} 72 + engines: {node: '>=6.9.0'} 73 + 74 + '@babel/parser@7.29.0': 75 + resolution: {integrity: sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==} 76 + engines: {node: '>=6.0.0'} 77 + hasBin: true 78 + 79 + '@babel/runtime@7.28.6': 80 + resolution: {integrity: sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==} 81 + engines: {node: '>=6.9.0'} 82 + 83 + '@babel/types@7.29.0': 84 + resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} 85 + engines: {node: '>=6.9.0'} 86 + 87 + '@braintree/sanitize-url@7.1.2': 88 + resolution: {integrity: sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA==} 89 + 90 + '@capsizecss/unpack@4.0.0': 91 + resolution: {integrity: sha512-VERIM64vtTP1C4mxQ5thVT9fK0apjPFobqybMtA1UdUujWka24ERHbRHFGmpbbhp73MhV+KSsHQH9C6uOTdEQA==} 92 + engines: {node: '>=18'} 93 + 94 + '@catppuccin/starlight@1.1.1': 95 + resolution: {integrity: sha512-iyI/gdGfqREetGti3O11l7iMLCmt0LRSbIis8ySlZo8hqb749KyMmisO/9kqBvk2oFKw9hGNDbutcNxKSI2spg==} 96 + peerDependencies: 97 + '@astrojs/starlight': '>=0.34' 98 + astro: ^5.0.0 99 + 100 + '@chevrotain/cst-dts-gen@11.1.1': 101 + resolution: {integrity: sha512-fRHyv6/f542qQqiRGalrfJl/evD39mAvbJLCekPazhiextEatq1Jx1K/i9gSd5NNO0ds03ek0Cbo/4uVKmOBcw==} 102 + 103 + '@chevrotain/gast@11.1.1': 104 + resolution: {integrity: sha512-Ko/5vPEYy1vn5CbCjjvnSO4U7GgxyGm+dfUZZJIWTlQFkXkyym0jFYrWEU10hyCjrA7rQtiHtBr0EaZqvHFZvg==} 105 + 106 + '@chevrotain/regexp-to-ast@11.1.1': 107 + resolution: {integrity: sha512-ctRw1OKSXkOrR8VTvOxrQ5USEc4sNrfwXHa1NuTcR7wre4YbjPcKw+82C2uylg/TEwFRgwLmbhlln4qkmDyteg==} 108 + 109 + '@chevrotain/types@11.1.1': 110 + resolution: {integrity: sha512-wb2ToxG8LkgPYnKe9FH8oGn3TMCBdnwiuNC5l5y+CtlaVRbCytU0kbVsk6CGrqTL4ZN4ksJa0TXOYbxpbthtqw==} 111 + 112 + '@chevrotain/utils@11.1.1': 113 + resolution: {integrity: sha512-71eTYMzYXYSFPrbg/ZwftSaSDld7UYlS8OQa3lNnn9jzNtpFbaReRRyghzqS7rI3CDaorqpPJJcXGHK+FE1TVQ==} 114 + 115 + '@ctrl/tinycolor@4.2.0': 116 + resolution: {integrity: sha512-kzyuwOAQnXJNLS9PSyrk0CWk35nWJW/zl/6KvnTBMFK65gm7U1/Z5BqjxeapjZCIhQcM/DsrEmcbRwDyXyXK4A==} 117 + engines: {node: '>=14'} 118 + 119 + '@emnapi/runtime@1.8.1': 120 + resolution: {integrity: sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==} 121 + 122 + '@esbuild/aix-ppc64@0.25.12': 123 + resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==} 124 + engines: {node: '>=18'} 125 + cpu: [ppc64] 126 + os: [aix] 127 + 128 + '@esbuild/aix-ppc64@0.27.3': 129 + resolution: {integrity: sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==} 130 + engines: {node: '>=18'} 131 + cpu: [ppc64] 132 + os: [aix] 133 + 134 + '@esbuild/android-arm64@0.25.12': 135 + resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==} 136 + engines: {node: '>=18'} 137 + cpu: [arm64] 138 + os: [android] 139 + 140 + '@esbuild/android-arm64@0.27.3': 141 + resolution: {integrity: sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==} 142 + engines: {node: '>=18'} 143 + cpu: [arm64] 144 + os: [android] 145 + 146 + '@esbuild/android-arm@0.25.12': 147 + resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==} 148 + engines: {node: '>=18'} 149 + cpu: [arm] 150 + os: [android] 151 + 152 + '@esbuild/android-arm@0.27.3': 153 + resolution: {integrity: sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==} 154 + engines: {node: '>=18'} 155 + cpu: [arm] 156 + os: [android] 157 + 158 + '@esbuild/android-x64@0.25.12': 159 + resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==} 160 + engines: {node: '>=18'} 161 + cpu: [x64] 162 + os: [android] 163 + 164 + '@esbuild/android-x64@0.27.3': 165 + resolution: {integrity: sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==} 166 + engines: {node: '>=18'} 167 + cpu: [x64] 168 + os: [android] 169 + 170 + '@esbuild/darwin-arm64@0.25.12': 171 + resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==} 172 + engines: {node: '>=18'} 173 + cpu: [arm64] 174 + os: [darwin] 175 + 176 + '@esbuild/darwin-arm64@0.27.3': 177 + resolution: {integrity: sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==} 178 + engines: {node: '>=18'} 179 + cpu: [arm64] 180 + os: [darwin] 181 + 182 + '@esbuild/darwin-x64@0.25.12': 183 + resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==} 184 + engines: {node: '>=18'} 185 + cpu: [x64] 186 + os: [darwin] 187 + 188 + '@esbuild/darwin-x64@0.27.3': 189 + resolution: {integrity: sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==} 190 + engines: {node: '>=18'} 191 + cpu: [x64] 192 + os: [darwin] 193 + 194 + '@esbuild/freebsd-arm64@0.25.12': 195 + resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==} 196 + engines: {node: '>=18'} 197 + cpu: [arm64] 198 + os: [freebsd] 199 + 200 + '@esbuild/freebsd-arm64@0.27.3': 201 + resolution: {integrity: sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==} 202 + engines: {node: '>=18'} 203 + cpu: [arm64] 204 + os: [freebsd] 205 + 206 + '@esbuild/freebsd-x64@0.25.12': 207 + resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==} 208 + engines: {node: '>=18'} 209 + cpu: [x64] 210 + os: [freebsd] 211 + 212 + '@esbuild/freebsd-x64@0.27.3': 213 + resolution: {integrity: sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==} 214 + engines: {node: '>=18'} 215 + cpu: [x64] 216 + os: [freebsd] 217 + 218 + '@esbuild/linux-arm64@0.25.12': 219 + resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==} 220 + engines: {node: '>=18'} 221 + cpu: [arm64] 222 + os: [linux] 223 + 224 + '@esbuild/linux-arm64@0.27.3': 225 + resolution: {integrity: sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==} 226 + engines: {node: '>=18'} 227 + cpu: [arm64] 228 + os: [linux] 229 + 230 + '@esbuild/linux-arm@0.25.12': 231 + resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==} 232 + engines: {node: '>=18'} 233 + cpu: [arm] 234 + os: [linux] 235 + 236 + '@esbuild/linux-arm@0.27.3': 237 + resolution: {integrity: sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==} 238 + engines: {node: '>=18'} 239 + cpu: [arm] 240 + os: [linux] 241 + 242 + '@esbuild/linux-ia32@0.25.12': 243 + resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==} 244 + engines: {node: '>=18'} 245 + cpu: [ia32] 246 + os: [linux] 247 + 248 + '@esbuild/linux-ia32@0.27.3': 249 + resolution: {integrity: sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==} 250 + engines: {node: '>=18'} 251 + cpu: [ia32] 252 + os: [linux] 253 + 254 + '@esbuild/linux-loong64@0.25.12': 255 + resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==} 256 + engines: {node: '>=18'} 257 + cpu: [loong64] 258 + os: [linux] 259 + 260 + '@esbuild/linux-loong64@0.27.3': 261 + resolution: {integrity: sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==} 262 + engines: {node: '>=18'} 263 + cpu: [loong64] 264 + os: [linux] 265 + 266 + '@esbuild/linux-mips64el@0.25.12': 267 + resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==} 268 + engines: {node: '>=18'} 269 + cpu: [mips64el] 270 + os: [linux] 271 + 272 + '@esbuild/linux-mips64el@0.27.3': 273 + resolution: {integrity: sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==} 274 + engines: {node: '>=18'} 275 + cpu: [mips64el] 276 + os: [linux] 277 + 278 + '@esbuild/linux-ppc64@0.25.12': 279 + resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==} 280 + engines: {node: '>=18'} 281 + cpu: [ppc64] 282 + os: [linux] 283 + 284 + '@esbuild/linux-ppc64@0.27.3': 285 + resolution: {integrity: sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==} 286 + engines: {node: '>=18'} 287 + cpu: [ppc64] 288 + os: [linux] 289 + 290 + '@esbuild/linux-riscv64@0.25.12': 291 + resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==} 292 + engines: {node: '>=18'} 293 + cpu: [riscv64] 294 + os: [linux] 295 + 296 + '@esbuild/linux-riscv64@0.27.3': 297 + resolution: {integrity: sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==} 298 + engines: {node: '>=18'} 299 + cpu: [riscv64] 300 + os: [linux] 301 + 302 + '@esbuild/linux-s390x@0.25.12': 303 + resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==} 304 + engines: {node: '>=18'} 305 + cpu: [s390x] 306 + os: [linux] 307 + 308 + '@esbuild/linux-s390x@0.27.3': 309 + resolution: {integrity: sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==} 310 + engines: {node: '>=18'} 311 + cpu: [s390x] 312 + os: [linux] 313 + 314 + '@esbuild/linux-x64@0.25.12': 315 + resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==} 316 + engines: {node: '>=18'} 317 + cpu: [x64] 318 + os: [linux] 319 + 320 + '@esbuild/linux-x64@0.27.3': 321 + resolution: {integrity: sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==} 322 + engines: {node: '>=18'} 323 + cpu: [x64] 324 + os: [linux] 325 + 326 + '@esbuild/netbsd-arm64@0.25.12': 327 + resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==} 328 + engines: {node: '>=18'} 329 + cpu: [arm64] 330 + os: [netbsd] 331 + 332 + '@esbuild/netbsd-arm64@0.27.3': 333 + resolution: {integrity: sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==} 334 + engines: {node: '>=18'} 335 + cpu: [arm64] 336 + os: [netbsd] 337 + 338 + '@esbuild/netbsd-x64@0.25.12': 339 + resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==} 340 + engines: {node: '>=18'} 341 + cpu: [x64] 342 + os: [netbsd] 343 + 344 + '@esbuild/netbsd-x64@0.27.3': 345 + resolution: {integrity: sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==} 346 + engines: {node: '>=18'} 347 + cpu: [x64] 348 + os: [netbsd] 349 + 350 + '@esbuild/openbsd-arm64@0.25.12': 351 + resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==} 352 + engines: {node: '>=18'} 353 + cpu: [arm64] 354 + os: [openbsd] 355 + 356 + '@esbuild/openbsd-arm64@0.27.3': 357 + resolution: {integrity: sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==} 358 + engines: {node: '>=18'} 359 + cpu: [arm64] 360 + os: [openbsd] 361 + 362 + '@esbuild/openbsd-x64@0.25.12': 363 + resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==} 364 + engines: {node: '>=18'} 365 + cpu: [x64] 366 + os: [openbsd] 367 + 368 + '@esbuild/openbsd-x64@0.27.3': 369 + resolution: {integrity: sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==} 370 + engines: {node: '>=18'} 371 + cpu: [x64] 372 + os: [openbsd] 373 + 374 + '@esbuild/openharmony-arm64@0.25.12': 375 + resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==} 376 + engines: {node: '>=18'} 377 + cpu: [arm64] 378 + os: [openharmony] 379 + 380 + '@esbuild/openharmony-arm64@0.27.3': 381 + resolution: {integrity: sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==} 382 + engines: {node: '>=18'} 383 + cpu: [arm64] 384 + os: [openharmony] 385 + 386 + '@esbuild/sunos-x64@0.25.12': 387 + resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==} 388 + engines: {node: '>=18'} 389 + cpu: [x64] 390 + os: [sunos] 391 + 392 + '@esbuild/sunos-x64@0.27.3': 393 + resolution: {integrity: sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==} 394 + engines: {node: '>=18'} 395 + cpu: [x64] 396 + os: [sunos] 397 + 398 + '@esbuild/win32-arm64@0.25.12': 399 + resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==} 400 + engines: {node: '>=18'} 401 + cpu: [arm64] 402 + os: [win32] 403 + 404 + '@esbuild/win32-arm64@0.27.3': 405 + resolution: {integrity: sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==} 406 + engines: {node: '>=18'} 407 + cpu: [arm64] 408 + os: [win32] 409 + 410 + '@esbuild/win32-ia32@0.25.12': 411 + resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==} 412 + engines: {node: '>=18'} 413 + cpu: [ia32] 414 + os: [win32] 415 + 416 + '@esbuild/win32-ia32@0.27.3': 417 + resolution: {integrity: sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==} 418 + engines: {node: '>=18'} 419 + cpu: [ia32] 420 + os: [win32] 421 + 422 + '@esbuild/win32-x64@0.25.12': 423 + resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==} 424 + engines: {node: '>=18'} 425 + cpu: [x64] 426 + os: [win32] 427 + 428 + '@esbuild/win32-x64@0.27.3': 429 + resolution: {integrity: sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==} 430 + engines: {node: '>=18'} 431 + cpu: [x64] 432 + os: [win32] 433 + 434 + '@expressive-code/core@0.41.6': 435 + resolution: {integrity: sha512-FvJQP+hG0jWi/FLBSmvHInDqWR7jNANp9PUDjdMqSshHb0y7sxx3vHuoOr6SgXjWw+MGLqorZyPQ0aAlHEok6g==} 436 + 437 + '@expressive-code/plugin-frames@0.41.6': 438 + resolution: {integrity: sha512-d+hkSYXIQot6fmYnOmWAM+7TNWRv/dhfjMsNq+mIZz8Tb4mPHOcgcfZeEM5dV9TDL0ioQNvtcqQNuzA1sRPjxg==} 439 + 440 + '@expressive-code/plugin-shiki@0.41.6': 441 + resolution: {integrity: sha512-Y6zmKBmsIUtWTzdefqlzm/h9Zz0Rc4gNdt2GTIH7fhHH2I9+lDYCa27BDwuBhjqcos6uK81Aca9dLUC4wzN+ng==} 442 + 443 + '@expressive-code/plugin-text-markers@0.41.6': 444 + resolution: {integrity: sha512-PBFa1wGyYzRExMDzBmAWC6/kdfG1oLn4pLpBeTfIRrALPjcGA/59HP3e7q9J0Smk4pC7U+lWkA2LHR8FYV8U7Q==} 445 + 446 + '@iconify/types@2.0.0': 447 + resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} 448 + 449 + '@iconify/utils@3.1.0': 450 + resolution: {integrity: sha512-Zlzem1ZXhI1iHeeERabLNzBHdOa4VhQbqAcOQaMKuTuyZCpwKbC2R4Dd0Zo3g9EAc+Y4fiarO8HIHRAth7+skw==} 451 + 452 + '@img/colour@1.0.0': 453 + resolution: {integrity: sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==} 454 + engines: {node: '>=18'} 455 + 456 + '@img/sharp-darwin-arm64@0.34.5': 457 + resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==} 458 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 459 + cpu: [arm64] 460 + os: [darwin] 461 + 462 + '@img/sharp-darwin-x64@0.34.5': 463 + resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==} 464 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 465 + cpu: [x64] 466 + os: [darwin] 467 + 468 + '@img/sharp-libvips-darwin-arm64@1.2.4': 469 + resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==} 470 + cpu: [arm64] 471 + os: [darwin] 472 + 473 + '@img/sharp-libvips-darwin-x64@1.2.4': 474 + resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==} 475 + cpu: [x64] 476 + os: [darwin] 477 + 478 + '@img/sharp-libvips-linux-arm64@1.2.4': 479 + resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} 480 + cpu: [arm64] 481 + os: [linux] 482 + 483 + '@img/sharp-libvips-linux-arm@1.2.4': 484 + resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} 485 + cpu: [arm] 486 + os: [linux] 487 + 488 + '@img/sharp-libvips-linux-ppc64@1.2.4': 489 + resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==} 490 + cpu: [ppc64] 491 + os: [linux] 492 + 493 + '@img/sharp-libvips-linux-riscv64@1.2.4': 494 + resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==} 495 + cpu: [riscv64] 496 + os: [linux] 497 + 498 + '@img/sharp-libvips-linux-s390x@1.2.4': 499 + resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} 500 + cpu: [s390x] 501 + os: [linux] 502 + 503 + '@img/sharp-libvips-linux-x64@1.2.4': 504 + resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} 505 + cpu: [x64] 506 + os: [linux] 507 + 508 + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': 509 + resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} 510 + cpu: [arm64] 511 + os: [linux] 512 + 513 + '@img/sharp-libvips-linuxmusl-x64@1.2.4': 514 + resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} 515 + cpu: [x64] 516 + os: [linux] 517 + 518 + '@img/sharp-linux-arm64@0.34.5': 519 + resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==} 520 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 521 + cpu: [arm64] 522 + os: [linux] 523 + 524 + '@img/sharp-linux-arm@0.34.5': 525 + resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==} 526 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 527 + cpu: [arm] 528 + os: [linux] 529 + 530 + '@img/sharp-linux-ppc64@0.34.5': 531 + resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==} 532 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 533 + cpu: [ppc64] 534 + os: [linux] 535 + 536 + '@img/sharp-linux-riscv64@0.34.5': 537 + resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==} 538 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 539 + cpu: [riscv64] 540 + os: [linux] 541 + 542 + '@img/sharp-linux-s390x@0.34.5': 543 + resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==} 544 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 545 + cpu: [s390x] 546 + os: [linux] 547 + 548 + '@img/sharp-linux-x64@0.34.5': 549 + resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==} 550 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 551 + cpu: [x64] 552 + os: [linux] 553 + 554 + '@img/sharp-linuxmusl-arm64@0.34.5': 555 + resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==} 556 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 557 + cpu: [arm64] 558 + os: [linux] 559 + 560 + '@img/sharp-linuxmusl-x64@0.34.5': 561 + resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==} 562 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 563 + cpu: [x64] 564 + os: [linux] 565 + 566 + '@img/sharp-wasm32@0.34.5': 567 + resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==} 568 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 569 + cpu: [wasm32] 570 + 571 + '@img/sharp-win32-arm64@0.34.5': 572 + resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==} 573 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 574 + cpu: [arm64] 575 + os: [win32] 576 + 577 + '@img/sharp-win32-ia32@0.34.5': 578 + resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==} 579 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 580 + cpu: [ia32] 581 + os: [win32] 582 + 583 + '@img/sharp-win32-x64@0.34.5': 584 + resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==} 585 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 586 + cpu: [x64] 587 + os: [win32] 588 + 589 + '@jridgewell/sourcemap-codec@1.5.5': 590 + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} 591 + 592 + '@mdx-js/mdx@3.1.1': 593 + resolution: {integrity: sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==} 594 + 595 + '@mermaid-js/parser@1.0.0': 596 + resolution: {integrity: sha512-vvK0Hi/VWndxoh03Mmz6wa1KDriSPjS2XMZL/1l19HFwygiObEEoEwSDxOqyLzzAI6J2PU3261JjTMTO7x+BPw==} 597 + 598 + '@oslojs/encoding@1.1.0': 599 + resolution: {integrity: sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==} 600 + 601 + '@pagefind/darwin-arm64@1.4.0': 602 + resolution: {integrity: sha512-2vMqkbv3lbx1Awea90gTaBsvpzgRs7MuSgKDxW0m9oV1GPZCZbZBJg/qL83GIUEN2BFlY46dtUZi54pwH+/pTQ==} 603 + cpu: [arm64] 604 + os: [darwin] 605 + 606 + '@pagefind/darwin-x64@1.4.0': 607 + resolution: {integrity: sha512-e7JPIS6L9/cJfow+/IAqknsGqEPjJnVXGjpGm25bnq+NPdoD3c/7fAwr1OXkG4Ocjx6ZGSCijXEV4ryMcH2E3A==} 608 + cpu: [x64] 609 + os: [darwin] 610 + 611 + '@pagefind/default-ui@1.4.0': 612 + resolution: {integrity: sha512-wie82VWn3cnGEdIjh4YwNESyS1G6vRHwL6cNjy9CFgNnWW/PGRjsLq300xjVH5sfPFK3iK36UxvIBymtQIEiSQ==} 613 + 614 + '@pagefind/freebsd-x64@1.4.0': 615 + resolution: {integrity: sha512-WcJVypXSZ+9HpiqZjFXMUobfFfZZ6NzIYtkhQ9eOhZrQpeY5uQFqNWLCk7w9RkMUwBv1HAMDW3YJQl/8OqsV0Q==} 616 + cpu: [x64] 617 + os: [freebsd] 618 + 619 + '@pagefind/linux-arm64@1.4.0': 620 + resolution: {integrity: sha512-PIt8dkqt4W06KGmQjONw7EZbhDF+uXI7i0XtRLN1vjCUxM9vGPdtJc2mUyVPevjomrGz5M86M8bqTr6cgDp1Uw==} 621 + cpu: [arm64] 622 + os: [linux] 623 + 624 + '@pagefind/linux-x64@1.4.0': 625 + resolution: {integrity: sha512-z4oddcWwQ0UHrTHR8psLnVlz6USGJ/eOlDPTDYZ4cI8TK8PgwRUPQZp9D2iJPNIPcS6Qx/E4TebjuGJOyK8Mmg==} 626 + cpu: [x64] 627 + os: [linux] 628 + 629 + '@pagefind/windows-x64@1.4.0': 630 + resolution: {integrity: sha512-NkT+YAdgS2FPCn8mIA9bQhiBs+xmniMGq1LFPDhcFn0+2yIUEiIG06t7bsZlhdjknEQRTSdT7YitP6fC5qwP0g==} 631 + cpu: [x64] 632 + os: [win32] 633 + 634 + '@rollup/pluginutils@5.3.0': 635 + resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==} 636 + engines: {node: '>=14.0.0'} 637 + peerDependencies: 638 + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 639 + peerDependenciesMeta: 640 + rollup: 641 + optional: true 642 + 643 + '@rollup/rollup-android-arm-eabi@4.57.1': 644 + resolution: {integrity: sha512-A6ehUVSiSaaliTxai040ZpZ2zTevHYbvu/lDoeAteHI8QnaosIzm4qwtezfRg1jOYaUmnzLX1AOD6Z+UJjtifg==} 645 + cpu: [arm] 646 + os: [android] 647 + 648 + '@rollup/rollup-android-arm64@4.57.1': 649 + resolution: {integrity: sha512-dQaAddCY9YgkFHZcFNS/606Exo8vcLHwArFZ7vxXq4rigo2bb494/xKMMwRRQW6ug7Js6yXmBZhSBRuBvCCQ3w==} 650 + cpu: [arm64] 651 + os: [android] 652 + 653 + '@rollup/rollup-darwin-arm64@4.57.1': 654 + resolution: {integrity: sha512-crNPrwJOrRxagUYeMn/DZwqN88SDmwaJ8Cvi/TN1HnWBU7GwknckyosC2gd0IqYRsHDEnXf328o9/HC6OkPgOg==} 655 + cpu: [arm64] 656 + os: [darwin] 657 + 658 + '@rollup/rollup-darwin-x64@4.57.1': 659 + resolution: {integrity: sha512-Ji8g8ChVbKrhFtig5QBV7iMaJrGtpHelkB3lsaKzadFBe58gmjfGXAOfI5FV0lYMH8wiqsxKQ1C9B0YTRXVy4w==} 660 + cpu: [x64] 661 + os: [darwin] 662 + 663 + '@rollup/rollup-freebsd-arm64@4.57.1': 664 + resolution: {integrity: sha512-R+/WwhsjmwodAcz65guCGFRkMb4gKWTcIeLy60JJQbXrJ97BOXHxnkPFrP+YwFlaS0m+uWJTstrUA9o+UchFug==} 665 + cpu: [arm64] 666 + os: [freebsd] 667 + 668 + '@rollup/rollup-freebsd-x64@4.57.1': 669 + resolution: {integrity: sha512-IEQTCHeiTOnAUC3IDQdzRAGj3jOAYNr9kBguI7MQAAZK3caezRrg0GxAb6Hchg4lxdZEI5Oq3iov/w/hnFWY9Q==} 670 + cpu: [x64] 671 + os: [freebsd] 672 + 673 + '@rollup/rollup-linux-arm-gnueabihf@4.57.1': 674 + resolution: {integrity: sha512-F8sWbhZ7tyuEfsmOxwc2giKDQzN3+kuBLPwwZGyVkLlKGdV1nvnNwYD0fKQ8+XS6hp9nY7B+ZeK01EBUE7aHaw==} 675 + cpu: [arm] 676 + os: [linux] 677 + 678 + '@rollup/rollup-linux-arm-musleabihf@4.57.1': 679 + resolution: {integrity: sha512-rGfNUfn0GIeXtBP1wL5MnzSj98+PZe/AXaGBCRmT0ts80lU5CATYGxXukeTX39XBKsxzFpEeK+Mrp9faXOlmrw==} 680 + cpu: [arm] 681 + os: [linux] 682 + 683 + '@rollup/rollup-linux-arm64-gnu@4.57.1': 684 + resolution: {integrity: sha512-MMtej3YHWeg/0klK2Qodf3yrNzz6CGjo2UntLvk2RSPlhzgLvYEB3frRvbEF2wRKh1Z2fDIg9KRPe1fawv7C+g==} 685 + cpu: [arm64] 686 + os: [linux] 687 + 688 + '@rollup/rollup-linux-arm64-musl@4.57.1': 689 + resolution: {integrity: sha512-1a/qhaaOXhqXGpMFMET9VqwZakkljWHLmZOX48R0I/YLbhdxr1m4gtG1Hq7++VhVUmf+L3sTAf9op4JlhQ5u1Q==} 690 + cpu: [arm64] 691 + os: [linux] 692 + 693 + '@rollup/rollup-linux-loong64-gnu@4.57.1': 694 + resolution: {integrity: sha512-QWO6RQTZ/cqYtJMtxhkRkidoNGXc7ERPbZN7dVW5SdURuLeVU7lwKMpo18XdcmpWYd0qsP1bwKPf7DNSUinhvA==} 695 + cpu: [loong64] 696 + os: [linux] 697 + 698 + '@rollup/rollup-linux-loong64-musl@4.57.1': 699 + resolution: {integrity: sha512-xpObYIf+8gprgWaPP32xiN5RVTi/s5FCR+XMXSKmhfoJjrpRAjCuuqQXyxUa/eJTdAE6eJ+KDKaoEqjZQxh3Gw==} 700 + cpu: [loong64] 701 + os: [linux] 702 + 703 + '@rollup/rollup-linux-ppc64-gnu@4.57.1': 704 + resolution: {integrity: sha512-4BrCgrpZo4hvzMDKRqEaW1zeecScDCR+2nZ86ATLhAoJ5FQ+lbHVD3ttKe74/c7tNT9c6F2viwB3ufwp01Oh2w==} 705 + cpu: [ppc64] 706 + os: [linux] 707 + 708 + '@rollup/rollup-linux-ppc64-musl@4.57.1': 709 + resolution: {integrity: sha512-NOlUuzesGauESAyEYFSe3QTUguL+lvrN1HtwEEsU2rOwdUDeTMJdO5dUYl/2hKf9jWydJrO9OL/XSSf65R5+Xw==} 710 + cpu: [ppc64] 711 + os: [linux] 712 + 713 + '@rollup/rollup-linux-riscv64-gnu@4.57.1': 714 + resolution: {integrity: sha512-ptA88htVp0AwUUqhVghwDIKlvJMD/fmL/wrQj99PRHFRAG6Z5nbWoWG4o81Nt9FT+IuqUQi+L31ZKAFeJ5Is+A==} 715 + cpu: [riscv64] 716 + os: [linux] 717 + 718 + '@rollup/rollup-linux-riscv64-musl@4.57.1': 719 + resolution: {integrity: sha512-S51t7aMMTNdmAMPpBg7OOsTdn4tySRQvklmL3RpDRyknk87+Sp3xaumlatU+ppQ+5raY7sSTcC2beGgvhENfuw==} 720 + cpu: [riscv64] 721 + os: [linux] 722 + 723 + '@rollup/rollup-linux-s390x-gnu@4.57.1': 724 + resolution: {integrity: sha512-Bl00OFnVFkL82FHbEqy3k5CUCKH6OEJL54KCyx2oqsmZnFTR8IoNqBF+mjQVcRCT5sB6yOvK8A37LNm/kPJiZg==} 725 + cpu: [s390x] 726 + os: [linux] 727 + 728 + '@rollup/rollup-linux-x64-gnu@4.57.1': 729 + resolution: {integrity: sha512-ABca4ceT4N+Tv/GtotnWAeXZUZuM/9AQyCyKYyKnpk4yoA7QIAuBt6Hkgpw8kActYlew2mvckXkvx0FfoInnLg==} 730 + cpu: [x64] 731 + os: [linux] 732 + 733 + '@rollup/rollup-linux-x64-musl@4.57.1': 734 + resolution: {integrity: sha512-HFps0JeGtuOR2convgRRkHCekD7j+gdAuXM+/i6kGzQtFhlCtQkpwtNzkNj6QhCDp7DRJ7+qC/1Vg2jt5iSOFw==} 735 + cpu: [x64] 736 + os: [linux] 737 + 738 + '@rollup/rollup-openbsd-x64@4.57.1': 739 + resolution: {integrity: sha512-H+hXEv9gdVQuDTgnqD+SQffoWoc0Of59AStSzTEj/feWTBAnSfSD3+Dql1ZruJQxmykT/JVY0dE8Ka7z0DH1hw==} 740 + cpu: [x64] 741 + os: [openbsd] 742 + 743 + '@rollup/rollup-openharmony-arm64@4.57.1': 744 + resolution: {integrity: sha512-4wYoDpNg6o/oPximyc/NG+mYUejZrCU2q+2w6YZqrAs2UcNUChIZXjtafAiiZSUc7On8v5NyNj34Kzj/Ltk6dQ==} 745 + cpu: [arm64] 746 + os: [openharmony] 747 + 748 + '@rollup/rollup-win32-arm64-msvc@4.57.1': 749 + resolution: {integrity: sha512-O54mtsV/6LW3P8qdTcamQmuC990HDfR71lo44oZMZlXU4tzLrbvTii87Ni9opq60ds0YzuAlEr/GNwuNluZyMQ==} 750 + cpu: [arm64] 751 + os: [win32] 752 + 753 + '@rollup/rollup-win32-ia32-msvc@4.57.1': 754 + resolution: {integrity: sha512-P3dLS+IerxCT/7D2q2FYcRdWRl22dNbrbBEtxdWhXrfIMPP9lQhb5h4Du04mdl5Woq05jVCDPCMF7Ub0NAjIew==} 755 + cpu: [ia32] 756 + os: [win32] 757 + 758 + '@rollup/rollup-win32-x64-gnu@4.57.1': 759 + resolution: {integrity: sha512-VMBH2eOOaKGtIJYleXsi2B8CPVADrh+TyNxJ4mWPnKfLB/DBUmzW+5m1xUrcwWoMfSLagIRpjUFeW5CO5hyciQ==} 760 + cpu: [x64] 761 + os: [win32] 762 + 763 + '@rollup/rollup-win32-x64-msvc@4.57.1': 764 + resolution: {integrity: sha512-mxRFDdHIWRxg3UfIIAwCm6NzvxG0jDX/wBN6KsQFTvKFqqg9vTrWUE68qEjHt19A5wwx5X5aUi2zuZT7YR0jrA==} 765 + cpu: [x64] 766 + os: [win32] 767 + 768 + '@shikijs/core@3.22.0': 769 + resolution: {integrity: sha512-iAlTtSDDbJiRpvgL5ugKEATDtHdUVkqgHDm/gbD2ZS9c88mx7G1zSYjjOxp5Qa0eaW0MAQosFRmJSk354PRoQA==} 770 + 771 + '@shikijs/engine-javascript@3.22.0': 772 + resolution: {integrity: sha512-jdKhfgW9CRtj3Tor0L7+yPwdG3CgP7W+ZEqSsojrMzCjD1e0IxIbwUMDDpYlVBlC08TACg4puwFGkZfLS+56Tw==} 773 + 774 + '@shikijs/engine-oniguruma@3.22.0': 775 + resolution: {integrity: sha512-DyXsOG0vGtNtl7ygvabHd7Mt5EY8gCNqR9Y7Lpbbd/PbJvgWrqaKzH1JW6H6qFkuUa8aCxoiYVv8/YfFljiQxA==} 776 + 777 + '@shikijs/langs@3.22.0': 778 + resolution: {integrity: sha512-x/42TfhWmp6H00T6uwVrdTJGKgNdFbrEdhaDwSR5fd5zhQ1Q46bHq9EO61SCEWJR0HY7z2HNDMaBZp8JRmKiIA==} 779 + 780 + '@shikijs/themes@3.22.0': 781 + resolution: {integrity: sha512-o+tlOKqsr6FE4+mYJG08tfCFDS+3CG20HbldXeVoyP+cYSUxDhrFf3GPjE60U55iOkkjbpY2uC3It/eeja35/g==} 782 + 783 + '@shikijs/types@3.22.0': 784 + resolution: {integrity: sha512-491iAekgKDBFE67z70Ok5a8KBMsQ2IJwOWw3us/7ffQkIBCyOQfm/aNwVMBUriP02QshIfgHCBSIYAl3u2eWjg==} 785 + 786 + '@shikijs/vscode-textmate@10.0.2': 787 + resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} 788 + 789 + '@types/d3-array@3.2.2': 790 + resolution: {integrity: sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==} 791 + 792 + '@types/d3-axis@3.0.6': 793 + resolution: {integrity: sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==} 794 + 795 + '@types/d3-brush@3.0.6': 796 + resolution: {integrity: sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==} 797 + 798 + '@types/d3-chord@3.0.6': 799 + resolution: {integrity: sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==} 800 + 801 + '@types/d3-color@3.1.3': 802 + resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==} 803 + 804 + '@types/d3-contour@3.0.6': 805 + resolution: {integrity: sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==} 806 + 807 + '@types/d3-delaunay@6.0.4': 808 + resolution: {integrity: sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==} 809 + 810 + '@types/d3-dispatch@3.0.7': 811 + resolution: {integrity: sha512-5o9OIAdKkhN1QItV2oqaE5KMIiXAvDWBDPrD85e58Qlz1c1kI/J0NcqbEG88CoTwJrYe7ntUCVfeUl2UJKbWgA==} 812 + 813 + '@types/d3-drag@3.0.7': 814 + resolution: {integrity: sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==} 815 + 816 + '@types/d3-dsv@3.0.7': 817 + resolution: {integrity: sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==} 818 + 819 + '@types/d3-ease@3.0.2': 820 + resolution: {integrity: sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==} 821 + 822 + '@types/d3-fetch@3.0.7': 823 + resolution: {integrity: sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==} 824 + 825 + '@types/d3-force@3.0.10': 826 + resolution: {integrity: sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==} 827 + 828 + '@types/d3-format@3.0.4': 829 + resolution: {integrity: sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==} 830 + 831 + '@types/d3-geo@3.1.0': 832 + resolution: {integrity: sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==} 833 + 834 + '@types/d3-hierarchy@3.1.7': 835 + resolution: {integrity: sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==} 836 + 837 + '@types/d3-interpolate@3.0.4': 838 + resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==} 839 + 840 + '@types/d3-path@3.1.1': 841 + resolution: {integrity: sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==} 842 + 843 + '@types/d3-polygon@3.0.2': 844 + resolution: {integrity: sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==} 845 + 846 + '@types/d3-quadtree@3.0.6': 847 + resolution: {integrity: sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==} 848 + 849 + '@types/d3-random@3.0.3': 850 + resolution: {integrity: sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==} 851 + 852 + '@types/d3-scale-chromatic@3.1.0': 853 + resolution: {integrity: sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==} 854 + 855 + '@types/d3-scale@4.0.9': 856 + resolution: {integrity: sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==} 857 + 858 + '@types/d3-selection@3.0.11': 859 + resolution: {integrity: sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==} 860 + 861 + '@types/d3-shape@3.1.8': 862 + resolution: {integrity: sha512-lae0iWfcDeR7qt7rA88BNiqdvPS5pFVPpo5OfjElwNaT2yyekbM0C9vK+yqBqEmHr6lDkRnYNoTBYlAgJa7a4w==} 863 + 864 + '@types/d3-time-format@4.0.3': 865 + resolution: {integrity: sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==} 866 + 867 + '@types/d3-time@3.0.4': 868 + resolution: {integrity: sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==} 869 + 870 + '@types/d3-timer@3.0.2': 871 + resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==} 872 + 873 + '@types/d3-transition@3.0.9': 874 + resolution: {integrity: sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==} 875 + 876 + '@types/d3-zoom@3.0.8': 877 + resolution: {integrity: sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==} 878 + 879 + '@types/d3@7.4.3': 880 + resolution: {integrity: sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==} 881 + 882 + '@types/debug@4.1.12': 883 + resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} 884 + 885 + '@types/estree-jsx@1.0.5': 886 + resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} 887 + 888 + '@types/estree@1.0.8': 889 + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} 890 + 891 + '@types/geojson@7946.0.16': 892 + resolution: {integrity: sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==} 893 + 894 + '@types/hast@3.0.4': 895 + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} 896 + 897 + '@types/js-yaml@4.0.9': 898 + resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} 899 + 900 + '@types/mdast@4.0.4': 901 + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} 902 + 903 + '@types/mdx@2.0.13': 904 + resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==} 905 + 906 + '@types/ms@2.1.0': 907 + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} 908 + 909 + '@types/nlcst@2.0.3': 910 + resolution: {integrity: sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==} 911 + 912 + '@types/node@17.0.45': 913 + resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==} 914 + 915 + '@types/sax@1.2.7': 916 + resolution: {integrity: sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==} 917 + 918 + '@types/trusted-types@2.0.7': 919 + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} 920 + 921 + '@types/unist@2.0.11': 922 + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} 923 + 924 + '@types/unist@3.0.3': 925 + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} 926 + 927 + '@ungap/structured-clone@1.3.0': 928 + resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} 929 + 930 + acorn-jsx@5.3.2: 931 + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} 932 + peerDependencies: 933 + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 934 + 935 + acorn@8.16.0: 936 + resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} 937 + engines: {node: '>=0.4.0'} 938 + hasBin: true 939 + 940 + ansi-align@3.0.1: 941 + resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} 942 + 943 + ansi-regex@5.0.1: 944 + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} 945 + engines: {node: '>=8'} 946 + 947 + ansi-regex@6.2.2: 948 + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} 949 + engines: {node: '>=12'} 950 + 951 + ansi-styles@6.2.3: 952 + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} 953 + engines: {node: '>=12'} 954 + 955 + anymatch@3.1.3: 956 + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} 957 + engines: {node: '>= 8'} 958 + 959 + arg@5.0.2: 960 + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} 961 + 962 + argparse@2.0.1: 963 + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} 964 + 965 + aria-query@5.3.2: 966 + resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} 967 + engines: {node: '>= 0.4'} 968 + 969 + array-iterate@2.0.1: 970 + resolution: {integrity: sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==} 971 + 972 + astring@1.9.0: 973 + resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} 974 + hasBin: true 975 + 976 + astro-expressive-code@0.41.6: 977 + resolution: {integrity: sha512-l47tb1uhmVIebHUkw+HEPtU/av0G4O8Q34g2cbkPvC7/e9ZhANcjUUciKt9Hp6gSVDdIuXBBLwJQn2LkeGMOAw==} 978 + peerDependencies: 979 + astro: ^4.0.0-beta || ^5.0.0-beta || ^3.3.0 || ^6.0.0-beta 980 + 981 + astro-mermaid@1.3.1: 982 + resolution: {integrity: sha512-1+FjwayMSZLtFd+ofdu1+v8a902nN5wmPmjY2qb8tLiO96YlL65LbskiuUcyH6q9h0CdZCrkc5FimlaHZsMJsg==} 983 + peerDependencies: 984 + '@mermaid-js/layout-elk': ^0.2.0 985 + astro: ^4.0.0 || ^5.0.0 986 + mermaid: ^10.0.0 || ^11.0.0 987 + peerDependenciesMeta: 988 + '@mermaid-js/layout-elk': 989 + optional: true 990 + 991 + astro@5.17.3: 992 + resolution: {integrity: sha512-69dcfPe8LsHzklwj+hl+vunWUbpMB6pmg35mACjetxbJeUNNys90JaBM8ZiwsPK689SAj/4Zqb1ayaANls9/MA==} 993 + engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0'} 994 + hasBin: true 995 + 996 + axobject-query@4.1.0: 997 + resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} 998 + engines: {node: '>= 0.4'} 999 + 1000 + bail@2.0.2: 1001 + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} 1002 + 1003 + base-64@1.0.0: 1004 + resolution: {integrity: sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==} 1005 + 1006 + bcp-47-match@2.0.3: 1007 + resolution: {integrity: sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==} 1008 + 1009 + bcp-47@2.1.0: 1010 + resolution: {integrity: sha512-9IIS3UPrvIa1Ej+lVDdDwO7zLehjqsaByECw0bu2RRGP73jALm6FYbzI5gWbgHLvNdkvfXB5YrSbocZdOS0c0w==} 1011 + 1012 + boolbase@1.0.0: 1013 + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} 1014 + 1015 + boxen@8.0.1: 1016 + resolution: {integrity: sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw==} 1017 + engines: {node: '>=18'} 1018 + 1019 + camelcase@8.0.0: 1020 + resolution: {integrity: sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==} 1021 + engines: {node: '>=16'} 1022 + 1023 + ccount@2.0.1: 1024 + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} 1025 + 1026 + chalk@5.6.2: 1027 + resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} 1028 + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} 1029 + 1030 + character-entities-html4@2.1.0: 1031 + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} 1032 + 1033 + character-entities-legacy@3.0.0: 1034 + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} 1035 + 1036 + character-entities@2.0.2: 1037 + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} 1038 + 1039 + character-reference-invalid@2.0.1: 1040 + resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} 1041 + 1042 + chevrotain-allstar@0.3.1: 1043 + resolution: {integrity: sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw==} 1044 + peerDependencies: 1045 + chevrotain: ^11.0.0 1046 + 1047 + chevrotain@11.1.1: 1048 + resolution: {integrity: sha512-f0yv5CPKaFxfsPTBzX7vGuim4oIC1/gcS7LUGdBSwl2dU6+FON6LVUksdOo1qJjoUvXNn45urgh8C+0a24pACQ==} 1049 + 1050 + chokidar@5.0.0: 1051 + resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} 1052 + engines: {node: '>= 20.19.0'} 1053 + 1054 + ci-info@4.4.0: 1055 + resolution: {integrity: sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==} 1056 + engines: {node: '>=8'} 1057 + 1058 + cli-boxes@3.0.0: 1059 + resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==} 1060 + engines: {node: '>=10'} 1061 + 1062 + clsx@2.1.1: 1063 + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} 1064 + engines: {node: '>=6'} 1065 + 1066 + collapse-white-space@2.1.0: 1067 + resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} 1068 + 1069 + comma-separated-tokens@2.0.3: 1070 + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} 1071 + 1072 + commander@11.1.0: 1073 + resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} 1074 + engines: {node: '>=16'} 1075 + 1076 + commander@7.2.0: 1077 + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} 1078 + engines: {node: '>= 10'} 1079 + 1080 + commander@8.3.0: 1081 + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} 1082 + engines: {node: '>= 12'} 1083 + 1084 + common-ancestor-path@1.0.1: 1085 + resolution: {integrity: sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==} 1086 + 1087 + confbox@0.1.8: 1088 + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} 1089 + 1090 + cookie-es@1.2.2: 1091 + resolution: {integrity: sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==} 1092 + 1093 + cookie@1.1.1: 1094 + resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} 1095 + engines: {node: '>=18'} 1096 + 1097 + cose-base@1.0.3: 1098 + resolution: {integrity: sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==} 1099 + 1100 + cose-base@2.2.0: 1101 + resolution: {integrity: sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==} 1102 + 1103 + crossws@0.3.5: 1104 + resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==} 1105 + 1106 + css-select@5.2.2: 1107 + resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} 1108 + 1109 + css-selector-parser@3.3.0: 1110 + resolution: {integrity: sha512-Y2asgMGFqJKF4fq4xHDSlFYIkeVfRsm69lQC1q9kbEsH5XtnINTMrweLkjYMeaUgiXBy/uvKeO/a1JHTNnmB2g==} 1111 + 1112 + css-tree@2.2.1: 1113 + resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==} 1114 + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} 1115 + 1116 + css-tree@3.1.0: 1117 + resolution: {integrity: sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==} 1118 + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} 1119 + 1120 + css-what@6.2.2: 1121 + resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} 1122 + engines: {node: '>= 6'} 1123 + 1124 + cssesc@3.0.0: 1125 + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} 1126 + engines: {node: '>=4'} 1127 + hasBin: true 1128 + 1129 + csso@5.0.5: 1130 + resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} 1131 + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} 1132 + 1133 + cytoscape-cose-bilkent@4.1.0: 1134 + resolution: {integrity: sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==} 1135 + peerDependencies: 1136 + cytoscape: ^3.2.0 1137 + 1138 + cytoscape-fcose@2.2.0: 1139 + resolution: {integrity: sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==} 1140 + peerDependencies: 1141 + cytoscape: ^3.2.0 1142 + 1143 + cytoscape@3.33.1: 1144 + resolution: {integrity: sha512-iJc4TwyANnOGR1OmWhsS9ayRS3s+XQ185FmuHObThD+5AeJCakAAbWv8KimMTt08xCCLNgneQwFp+JRJOr9qGQ==} 1145 + engines: {node: '>=0.10'} 1146 + 1147 + d3-array@2.12.1: 1148 + resolution: {integrity: sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==} 1149 + 1150 + d3-array@3.2.4: 1151 + resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} 1152 + engines: {node: '>=12'} 1153 + 1154 + d3-axis@3.0.0: 1155 + resolution: {integrity: sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==} 1156 + engines: {node: '>=12'} 1157 + 1158 + d3-brush@3.0.0: 1159 + resolution: {integrity: sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==} 1160 + engines: {node: '>=12'} 1161 + 1162 + d3-chord@3.0.1: 1163 + resolution: {integrity: sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==} 1164 + engines: {node: '>=12'} 1165 + 1166 + d3-color@3.1.0: 1167 + resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==} 1168 + engines: {node: '>=12'} 1169 + 1170 + d3-contour@4.0.2: 1171 + resolution: {integrity: sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==} 1172 + engines: {node: '>=12'} 1173 + 1174 + d3-delaunay@6.0.4: 1175 + resolution: {integrity: sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==} 1176 + engines: {node: '>=12'} 1177 + 1178 + d3-dispatch@3.0.1: 1179 + resolution: {integrity: sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==} 1180 + engines: {node: '>=12'} 1181 + 1182 + d3-drag@3.0.0: 1183 + resolution: {integrity: sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==} 1184 + engines: {node: '>=12'} 1185 + 1186 + d3-dsv@3.0.1: 1187 + resolution: {integrity: sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==} 1188 + engines: {node: '>=12'} 1189 + hasBin: true 1190 + 1191 + d3-ease@3.0.1: 1192 + resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==} 1193 + engines: {node: '>=12'} 1194 + 1195 + d3-fetch@3.0.1: 1196 + resolution: {integrity: sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==} 1197 + engines: {node: '>=12'} 1198 + 1199 + d3-force@3.0.0: 1200 + resolution: {integrity: sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==} 1201 + engines: {node: '>=12'} 1202 + 1203 + d3-format@3.1.2: 1204 + resolution: {integrity: sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==} 1205 + engines: {node: '>=12'} 1206 + 1207 + d3-geo@3.1.1: 1208 + resolution: {integrity: sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==} 1209 + engines: {node: '>=12'} 1210 + 1211 + d3-hierarchy@3.1.2: 1212 + resolution: {integrity: sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==} 1213 + engines: {node: '>=12'} 1214 + 1215 + d3-interpolate@3.0.1: 1216 + resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} 1217 + engines: {node: '>=12'} 1218 + 1219 + d3-path@1.0.9: 1220 + resolution: {integrity: sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==} 1221 + 1222 + d3-path@3.1.0: 1223 + resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==} 1224 + engines: {node: '>=12'} 1225 + 1226 + d3-polygon@3.0.1: 1227 + resolution: {integrity: sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==} 1228 + engines: {node: '>=12'} 1229 + 1230 + d3-quadtree@3.0.1: 1231 + resolution: {integrity: sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==} 1232 + engines: {node: '>=12'} 1233 + 1234 + d3-random@3.0.1: 1235 + resolution: {integrity: sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==} 1236 + engines: {node: '>=12'} 1237 + 1238 + d3-sankey@0.12.3: 1239 + resolution: {integrity: sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==} 1240 + 1241 + d3-scale-chromatic@3.1.0: 1242 + resolution: {integrity: sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==} 1243 + engines: {node: '>=12'} 1244 + 1245 + d3-scale@4.0.2: 1246 + resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==} 1247 + engines: {node: '>=12'} 1248 + 1249 + d3-selection@3.0.0: 1250 + resolution: {integrity: sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==} 1251 + engines: {node: '>=12'} 1252 + 1253 + d3-shape@1.3.7: 1254 + resolution: {integrity: sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==} 1255 + 1256 + d3-shape@3.2.0: 1257 + resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==} 1258 + engines: {node: '>=12'} 1259 + 1260 + d3-time-format@4.1.0: 1261 + resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==} 1262 + engines: {node: '>=12'} 1263 + 1264 + d3-time@3.1.0: 1265 + resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==} 1266 + engines: {node: '>=12'} 1267 + 1268 + d3-timer@3.0.1: 1269 + resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==} 1270 + engines: {node: '>=12'} 1271 + 1272 + d3-transition@3.0.1: 1273 + resolution: {integrity: sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==} 1274 + engines: {node: '>=12'} 1275 + peerDependencies: 1276 + d3-selection: 2 - 3 1277 + 1278 + d3-zoom@3.0.0: 1279 + resolution: {integrity: sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==} 1280 + engines: {node: '>=12'} 1281 + 1282 + d3@7.9.0: 1283 + resolution: {integrity: sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==} 1284 + engines: {node: '>=12'} 1285 + 1286 + dagre-d3-es@7.0.13: 1287 + resolution: {integrity: sha512-efEhnxpSuwpYOKRm/L5KbqoZmNNukHa/Flty4Wp62JRvgH2ojwVgPgdYyr4twpieZnyRDdIH7PY2mopX26+j2Q==} 1288 + 1289 + dayjs@1.11.19: 1290 + resolution: {integrity: sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==} 1291 + 1292 + debug@4.4.3: 1293 + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} 1294 + engines: {node: '>=6.0'} 1295 + peerDependencies: 1296 + supports-color: '*' 1297 + peerDependenciesMeta: 1298 + supports-color: 1299 + optional: true 1300 + 1301 + decode-named-character-reference@1.3.0: 1302 + resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} 1303 + 1304 + defu@6.1.4: 1305 + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} 1306 + 1307 + delaunator@5.0.1: 1308 + resolution: {integrity: sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==} 1309 + 1310 + dequal@2.0.3: 1311 + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} 1312 + engines: {node: '>=6'} 1313 + 1314 + destr@2.0.5: 1315 + resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} 1316 + 1317 + detect-libc@2.1.2: 1318 + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} 1319 + engines: {node: '>=8'} 1320 + 1321 + deterministic-object-hash@2.0.2: 1322 + resolution: {integrity: sha512-KxektNH63SrbfUyDiwXqRb1rLwKt33AmMv+5Nhsw1kqZ13SJBRTgZHtGbE+hH3a1mVW1cz+4pqSWVPAtLVXTzQ==} 1323 + engines: {node: '>=18'} 1324 + 1325 + devalue@5.6.3: 1326 + resolution: {integrity: sha512-nc7XjUU/2Lb+SvEFVGcWLiKkzfw8+qHI7zn8WYXKkLMgfGSHbgCEaR6bJpev8Cm6Rmrb19Gfd/tZvGqx9is3wg==} 1327 + 1328 + devlop@1.1.0: 1329 + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} 1330 + 1331 + diff@8.0.3: 1332 + resolution: {integrity: sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==} 1333 + engines: {node: '>=0.3.1'} 1334 + 1335 + direction@2.0.1: 1336 + resolution: {integrity: sha512-9S6m9Sukh1cZNknO1CWAr2QAWsbKLafQiyM5gZ7VgXHeuaoUwffKN4q6NC4A/Mf9iiPlOXQEKW/Mv/mh9/3YFA==} 1337 + hasBin: true 1338 + 1339 + dlv@1.1.3: 1340 + resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} 1341 + 1342 + dom-serializer@2.0.0: 1343 + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} 1344 + 1345 + domelementtype@2.3.0: 1346 + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} 1347 + 1348 + domhandler@5.0.3: 1349 + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} 1350 + engines: {node: '>= 4'} 1351 + 1352 + dompurify@3.3.1: 1353 + resolution: {integrity: sha512-qkdCKzLNtrgPFP1Vo+98FRzJnBRGe4ffyCea9IwHB1fyxPOeNTHpLKYGd4Uk9xvNoH0ZoOjwZxNptyMwqrId1Q==} 1354 + 1355 + domutils@3.2.2: 1356 + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} 1357 + 1358 + dset@3.1.4: 1359 + resolution: {integrity: sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==} 1360 + engines: {node: '>=4'} 1361 + 1362 + emoji-regex@10.6.0: 1363 + resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} 1364 + 1365 + emoji-regex@8.0.0: 1366 + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} 1367 + 1368 + entities@4.5.0: 1369 + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} 1370 + engines: {node: '>=0.12'} 1371 + 1372 + entities@6.0.1: 1373 + resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} 1374 + engines: {node: '>=0.12'} 1375 + 1376 + es-module-lexer@1.7.0: 1377 + resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} 1378 + 1379 + esast-util-from-estree@2.0.0: 1380 + resolution: {integrity: sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==} 1381 + 1382 + esast-util-from-js@2.0.1: 1383 + resolution: {integrity: sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==} 1384 + 1385 + esbuild@0.25.12: 1386 + resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==} 1387 + engines: {node: '>=18'} 1388 + hasBin: true 1389 + 1390 + esbuild@0.27.3: 1391 + resolution: {integrity: sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==} 1392 + engines: {node: '>=18'} 1393 + hasBin: true 1394 + 1395 + escape-string-regexp@5.0.0: 1396 + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} 1397 + engines: {node: '>=12'} 1398 + 1399 + estree-util-attach-comments@3.0.0: 1400 + resolution: {integrity: sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==} 1401 + 1402 + estree-util-build-jsx@3.0.1: 1403 + resolution: {integrity: sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==} 1404 + 1405 + estree-util-is-identifier-name@3.0.0: 1406 + resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} 1407 + 1408 + estree-util-scope@1.0.0: 1409 + resolution: {integrity: sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==} 1410 + 1411 + estree-util-to-js@2.0.0: 1412 + resolution: {integrity: sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==} 1413 + 1414 + estree-util-visit@2.0.0: 1415 + resolution: {integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==} 1416 + 1417 + estree-walker@2.0.2: 1418 + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} 1419 + 1420 + estree-walker@3.0.3: 1421 + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} 1422 + 1423 + eventemitter3@5.0.4: 1424 + resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==} 1425 + 1426 + expressive-code@0.41.6: 1427 + resolution: {integrity: sha512-W/5+IQbrpCIM5KGLjO35wlp1NCwDOOVQb+PAvzEoGkW1xjGM807ZGfBKptNWH6UECvt6qgmLyWolCMYKh7eQmA==} 1428 + 1429 + extend@3.0.2: 1430 + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} 1431 + 1432 + fdir@6.5.0: 1433 + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} 1434 + engines: {node: '>=12.0.0'} 1435 + peerDependencies: 1436 + picomatch: ^3 || ^4 1437 + peerDependenciesMeta: 1438 + picomatch: 1439 + optional: true 1440 + 1441 + flattie@1.1.1: 1442 + resolution: {integrity: sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==} 1443 + engines: {node: '>=8'} 1444 + 1445 + fontace@0.4.1: 1446 + resolution: {integrity: sha512-lDMvbAzSnHmbYMTEld5qdtvNH2/pWpICOqpean9IgC7vUbUJc3k+k5Dokp85CegamqQpFbXf0rAVkbzpyTA8aw==} 1447 + 1448 + fontkitten@1.0.2: 1449 + resolution: {integrity: sha512-piJxbLnkD9Xcyi7dWJRnqszEURixe7CrF/efBfbffe2DPyabmuIuqraruY8cXTs19QoM8VJzx47BDRVNXETM7Q==} 1450 + engines: {node: '>=20'} 1451 + 1452 + fsevents@2.3.3: 1453 + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} 1454 + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 1455 + os: [darwin] 1456 + 1457 + get-east-asian-width@1.5.0: 1458 + resolution: {integrity: sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==} 1459 + engines: {node: '>=18'} 1460 + 1461 + github-slugger@2.0.0: 1462 + resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==} 1463 + 1464 + h3@1.15.5: 1465 + resolution: {integrity: sha512-xEyq3rSl+dhGX2Lm0+eFQIAzlDN6Fs0EcC4f7BNUmzaRX/PTzeuM+Tr2lHB8FoXggsQIeXLj8EDVgs5ywxyxmg==} 1466 + 1467 + hachure-fill@0.5.2: 1468 + resolution: {integrity: sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==} 1469 + 1470 + hast-util-embedded@3.0.0: 1471 + resolution: {integrity: sha512-naH8sld4Pe2ep03qqULEtvYr7EjrLK2QHY8KJR6RJkTUjPGObe1vnx585uzem2hGra+s1q08DZZpfgDVYRbaXA==} 1472 + 1473 + hast-util-format@1.1.0: 1474 + resolution: {integrity: sha512-yY1UDz6bC9rDvCWHpx12aIBGRG7krurX0p0Fm6pT547LwDIZZiNr8a+IHDogorAdreULSEzP82Nlv5SZkHZcjA==} 1475 + 1476 + hast-util-from-html@2.0.3: 1477 + resolution: {integrity: sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==} 1478 + 1479 + hast-util-from-parse5@8.0.3: 1480 + resolution: {integrity: sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==} 1481 + 1482 + hast-util-has-property@3.0.0: 1483 + resolution: {integrity: sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA==} 1484 + 1485 + hast-util-is-body-ok-link@3.0.1: 1486 + resolution: {integrity: sha512-0qpnzOBLztXHbHQenVB8uNuxTnm/QBFUOmdOSsEn7GnBtyY07+ENTWVFBAnXd/zEgd9/SUG3lRY7hSIBWRgGpQ==} 1487 + 1488 + hast-util-is-element@3.0.0: 1489 + resolution: {integrity: sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==} 1490 + 1491 + hast-util-minify-whitespace@1.0.1: 1492 + resolution: {integrity: sha512-L96fPOVpnclQE0xzdWb/D12VT5FabA7SnZOUMtL1DbXmYiHJMXZvFkIZfiMmTCNJHUeO2K9UYNXoVyfz+QHuOw==} 1493 + 1494 + hast-util-parse-selector@4.0.0: 1495 + resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==} 1496 + 1497 + hast-util-phrasing@3.0.1: 1498 + resolution: {integrity: sha512-6h60VfI3uBQUxHqTyMymMZnEbNl1XmEGtOxxKYL7stY2o601COo62AWAYBQR9lZbYXYSBoxag8UpPRXK+9fqSQ==} 1499 + 1500 + hast-util-raw@9.1.0: 1501 + resolution: {integrity: sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==} 1502 + 1503 + hast-util-select@6.0.4: 1504 + resolution: {integrity: sha512-RqGS1ZgI0MwxLaKLDxjprynNzINEkRHY2i8ln4DDjgv9ZhcYVIHN9rlpiYsqtFwrgpYU361SyWDQcGNIBVu3lw==} 1505 + 1506 + hast-util-to-estree@3.1.3: 1507 + resolution: {integrity: sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==} 1508 + 1509 + hast-util-to-html@9.0.5: 1510 + resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==} 1511 + 1512 + hast-util-to-jsx-runtime@2.3.6: 1513 + resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==} 1514 + 1515 + hast-util-to-parse5@8.0.1: 1516 + resolution: {integrity: sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==} 1517 + 1518 + hast-util-to-string@3.0.1: 1519 + resolution: {integrity: sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==} 1520 + 1521 + hast-util-to-text@4.0.2: 1522 + resolution: {integrity: sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==} 1523 + 1524 + hast-util-whitespace@3.0.0: 1525 + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} 1526 + 1527 + hastscript@9.0.1: 1528 + resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==} 1529 + 1530 + html-escaper@3.0.3: 1531 + resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==} 1532 + 1533 + html-void-elements@3.0.0: 1534 + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} 1535 + 1536 + html-whitespace-sensitive-tag-names@3.0.1: 1537 + resolution: {integrity: sha512-q+310vW8zmymYHALr1da4HyXUQ0zgiIwIicEfotYPWGN0OJVEN/58IJ3A4GBYcEq3LGAZqKb+ugvP0GNB9CEAA==} 1538 + 1539 + http-cache-semantics@4.2.0: 1540 + resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} 1541 + 1542 + i18next@23.16.8: 1543 + resolution: {integrity: sha512-06r/TitrM88Mg5FdUXAKL96dJMzgqLE5dv3ryBAra4KCwD9mJ4ndOTS95ZuymIGoE+2hzfdaMak2X11/es7ZWg==} 1544 + 1545 + iconv-lite@0.6.3: 1546 + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} 1547 + engines: {node: '>=0.10.0'} 1548 + 1549 + import-meta-resolve@4.2.0: 1550 + resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==} 1551 + 1552 + inline-style-parser@0.2.7: 1553 + resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==} 1554 + 1555 + internmap@1.0.1: 1556 + resolution: {integrity: sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==} 1557 + 1558 + internmap@2.0.3: 1559 + resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} 1560 + engines: {node: '>=12'} 1561 + 1562 + iron-webcrypto@1.2.1: 1563 + resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} 1564 + 1565 + is-alphabetical@2.0.1: 1566 + resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} 1567 + 1568 + is-alphanumerical@2.0.1: 1569 + resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} 1570 + 1571 + is-decimal@2.0.1: 1572 + resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} 1573 + 1574 + is-docker@3.0.0: 1575 + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} 1576 + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 1577 + hasBin: true 1578 + 1579 + is-fullwidth-code-point@3.0.0: 1580 + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} 1581 + engines: {node: '>=8'} 1582 + 1583 + is-hexadecimal@2.0.1: 1584 + resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} 1585 + 1586 + is-inside-container@1.0.0: 1587 + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} 1588 + engines: {node: '>=14.16'} 1589 + hasBin: true 1590 + 1591 + is-plain-obj@4.1.0: 1592 + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} 1593 + engines: {node: '>=12'} 1594 + 1595 + is-wsl@3.1.1: 1596 + resolution: {integrity: sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==} 1597 + engines: {node: '>=16'} 1598 + 1599 + js-yaml@4.1.1: 1600 + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} 1601 + hasBin: true 1602 + 1603 + katex@0.16.28: 1604 + resolution: {integrity: sha512-YHzO7721WbmAL6Ov1uzN/l5mY5WWWhJBSW+jq4tkfZfsxmo1hu6frS0EOswvjBUnWE6NtjEs48SFn5CQESRLZg==} 1605 + hasBin: true 1606 + 1607 + khroma@2.1.0: 1608 + resolution: {integrity: sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==} 1609 + 1610 + kleur@3.0.3: 1611 + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} 1612 + engines: {node: '>=6'} 1613 + 1614 + klona@2.0.6: 1615 + resolution: {integrity: sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==} 1616 + engines: {node: '>= 8'} 1617 + 1618 + langium@4.2.1: 1619 + resolution: {integrity: sha512-zu9QWmjpzJcomzdJQAHgDVhLGq5bLosVak1KVa40NzQHXfqr4eAHupvnPOVXEoLkg6Ocefvf/93d//SB7du4YQ==} 1620 + engines: {node: '>=20.10.0', npm: '>=10.2.3'} 1621 + 1622 + layout-base@1.0.2: 1623 + resolution: {integrity: sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==} 1624 + 1625 + layout-base@2.0.1: 1626 + resolution: {integrity: sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==} 1627 + 1628 + lodash-es@4.17.23: 1629 + resolution: {integrity: sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==} 1630 + 1631 + longest-streak@3.1.0: 1632 + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} 1633 + 1634 + lru-cache@11.2.6: 1635 + resolution: {integrity: sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==} 1636 + engines: {node: 20 || >=22} 1637 + 1638 + magic-string@0.30.21: 1639 + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} 1640 + 1641 + magicast@0.5.2: 1642 + resolution: {integrity: sha512-E3ZJh4J3S9KfwdjZhe2afj6R9lGIN5Pher1pF39UGrXRqq/VDaGVIGN13BjHd2u8B61hArAGOnso7nBOouW3TQ==} 1643 + 1644 + markdown-extensions@2.0.0: 1645 + resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==} 1646 + engines: {node: '>=16'} 1647 + 1648 + markdown-table@3.0.4: 1649 + resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} 1650 + 1651 + marked@16.4.2: 1652 + resolution: {integrity: sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA==} 1653 + engines: {node: '>= 20'} 1654 + hasBin: true 1655 + 1656 + mdast-util-definitions@6.0.0: 1657 + resolution: {integrity: sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==} 1658 + 1659 + mdast-util-directive@3.1.0: 1660 + resolution: {integrity: sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q==} 1661 + 1662 + mdast-util-find-and-replace@3.0.2: 1663 + resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} 1664 + 1665 + mdast-util-from-markdown@2.0.2: 1666 + resolution: {integrity: sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==} 1667 + 1668 + mdast-util-gfm-autolink-literal@2.0.1: 1669 + resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} 1670 + 1671 + mdast-util-gfm-footnote@2.1.0: 1672 + resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==} 1673 + 1674 + mdast-util-gfm-strikethrough@2.0.0: 1675 + resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} 1676 + 1677 + mdast-util-gfm-table@2.0.0: 1678 + resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} 1679 + 1680 + mdast-util-gfm-task-list-item@2.0.0: 1681 + resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} 1682 + 1683 + mdast-util-gfm@3.1.0: 1684 + resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} 1685 + 1686 + mdast-util-mdx-expression@2.0.1: 1687 + resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==} 1688 + 1689 + mdast-util-mdx-jsx@3.2.0: 1690 + resolution: {integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==} 1691 + 1692 + mdast-util-mdx@3.0.0: 1693 + resolution: {integrity: sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==} 1694 + 1695 + mdast-util-mdxjs-esm@2.0.1: 1696 + resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==} 1697 + 1698 + mdast-util-phrasing@4.1.0: 1699 + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} 1700 + 1701 + mdast-util-to-hast@13.2.1: 1702 + resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==} 1703 + 1704 + mdast-util-to-markdown@2.1.2: 1705 + resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} 1706 + 1707 + mdast-util-to-string@4.0.0: 1708 + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} 1709 + 1710 + mdn-data@2.0.28: 1711 + resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==} 1712 + 1713 + mdn-data@2.12.2: 1714 + resolution: {integrity: sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==} 1715 + 1716 + mermaid@11.12.3: 1717 + resolution: {integrity: sha512-wN5ZSgJQIC+CHJut9xaKWsknLxaFBwCPwPkGTSUYrTiHORWvpT8RxGk849HPnpUAQ+/9BPRqYb80jTpearrHzQ==} 1718 + 1719 + micromark-core-commonmark@2.0.3: 1720 + resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} 1721 + 1722 + micromark-extension-directive@3.0.2: 1723 + resolution: {integrity: sha512-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA==} 1724 + 1725 + micromark-extension-gfm-autolink-literal@2.1.0: 1726 + resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} 1727 + 1728 + micromark-extension-gfm-footnote@2.1.0: 1729 + resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} 1730 + 1731 + micromark-extension-gfm-strikethrough@2.1.0: 1732 + resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} 1733 + 1734 + micromark-extension-gfm-table@2.1.1: 1735 + resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==} 1736 + 1737 + micromark-extension-gfm-tagfilter@2.0.0: 1738 + resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} 1739 + 1740 + micromark-extension-gfm-task-list-item@2.1.0: 1741 + resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==} 1742 + 1743 + micromark-extension-gfm@3.0.0: 1744 + resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} 1745 + 1746 + micromark-extension-mdx-expression@3.0.1: 1747 + resolution: {integrity: sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==} 1748 + 1749 + micromark-extension-mdx-jsx@3.0.2: 1750 + resolution: {integrity: sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==} 1751 + 1752 + micromark-extension-mdx-md@2.0.0: 1753 + resolution: {integrity: sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==} 1754 + 1755 + micromark-extension-mdxjs-esm@3.0.0: 1756 + resolution: {integrity: sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==} 1757 + 1758 + micromark-extension-mdxjs@3.0.0: 1759 + resolution: {integrity: sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==} 1760 + 1761 + micromark-factory-destination@2.0.1: 1762 + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} 1763 + 1764 + micromark-factory-label@2.0.1: 1765 + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} 1766 + 1767 + micromark-factory-mdx-expression@2.0.3: 1768 + resolution: {integrity: sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==} 1769 + 1770 + micromark-factory-space@2.0.1: 1771 + resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} 1772 + 1773 + micromark-factory-title@2.0.1: 1774 + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} 1775 + 1776 + micromark-factory-whitespace@2.0.1: 1777 + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} 1778 + 1779 + micromark-util-character@2.1.1: 1780 + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} 1781 + 1782 + micromark-util-chunked@2.0.1: 1783 + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} 1784 + 1785 + micromark-util-classify-character@2.0.1: 1786 + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} 1787 + 1788 + micromark-util-combine-extensions@2.0.1: 1789 + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} 1790 + 1791 + micromark-util-decode-numeric-character-reference@2.0.2: 1792 + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} 1793 + 1794 + micromark-util-decode-string@2.0.1: 1795 + resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} 1796 + 1797 + micromark-util-encode@2.0.1: 1798 + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} 1799 + 1800 + micromark-util-events-to-acorn@2.0.3: 1801 + resolution: {integrity: sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==} 1802 + 1803 + micromark-util-html-tag-name@2.0.1: 1804 + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} 1805 + 1806 + micromark-util-normalize-identifier@2.0.1: 1807 + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} 1808 + 1809 + micromark-util-resolve-all@2.0.1: 1810 + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} 1811 + 1812 + micromark-util-sanitize-uri@2.0.1: 1813 + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} 1814 + 1815 + micromark-util-subtokenize@2.1.0: 1816 + resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} 1817 + 1818 + micromark-util-symbol@2.0.1: 1819 + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} 1820 + 1821 + micromark-util-types@2.0.2: 1822 + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} 1823 + 1824 + micromark@4.0.2: 1825 + resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} 1826 + 1827 + mlly@1.8.0: 1828 + resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==} 1829 + 1830 + mrmime@2.0.1: 1831 + resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} 1832 + engines: {node: '>=10'} 1833 + 1834 + ms@2.1.3: 1835 + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} 1836 + 1837 + nanoid@3.3.11: 1838 + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} 1839 + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} 1840 + hasBin: true 1841 + 1842 + neotraverse@0.6.18: 1843 + resolution: {integrity: sha512-Z4SmBUweYa09+o6pG+eASabEpP6QkQ70yHj351pQoEXIs8uHbaU2DWVmzBANKgflPa47A50PtB2+NgRpQvr7vA==} 1844 + engines: {node: '>= 10'} 1845 + 1846 + nlcst-to-string@4.0.0: 1847 + resolution: {integrity: sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA==} 1848 + 1849 + node-fetch-native@1.6.7: 1850 + resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} 1851 + 1852 + node-mock-http@1.0.4: 1853 + resolution: {integrity: sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ==} 1854 + 1855 + normalize-path@3.0.0: 1856 + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} 1857 + engines: {node: '>=0.10.0'} 1858 + 1859 + nth-check@2.1.1: 1860 + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} 1861 + 1862 + ofetch@1.5.1: 1863 + resolution: {integrity: sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==} 1864 + 1865 + ohash@2.0.11: 1866 + resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} 1867 + 1868 + oniguruma-parser@0.12.1: 1869 + resolution: {integrity: sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==} 1870 + 1871 + oniguruma-to-es@4.3.4: 1872 + resolution: {integrity: sha512-3VhUGN3w2eYxnTzHn+ikMI+fp/96KoRSVK9/kMTcFqj1NRDh2IhQCKvYxDnWePKRXY/AqH+Fuiyb7VHSzBjHfA==} 1873 + 1874 + p-limit@6.2.0: 1875 + resolution: {integrity: sha512-kuUqqHNUqoIWp/c467RI4X6mmyuojY5jGutNU0wVTmEOOfcuwLqyMVoAi9MKi2Ak+5i9+nhmrK4ufZE8069kHA==} 1876 + engines: {node: '>=18'} 1877 + 1878 + p-queue@8.1.1: 1879 + resolution: {integrity: sha512-aNZ+VfjobsWryoiPnEApGGmf5WmNsCo9xu8dfaYamG5qaLP7ClhLN6NgsFe6SwJ2UbLEBK5dv9x8Mn5+RVhMWQ==} 1880 + engines: {node: '>=18'} 1881 + 1882 + p-timeout@6.1.4: 1883 + resolution: {integrity: sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==} 1884 + engines: {node: '>=14.16'} 1885 + 1886 + package-manager-detector@1.6.0: 1887 + resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==} 1888 + 1889 + pagefind@1.4.0: 1890 + resolution: {integrity: sha512-z2kY1mQlL4J8q5EIsQkLzQjilovKzfNVhX8De6oyE6uHpfFtyBaqUpcl/XzJC/4fjD8vBDyh1zolimIcVrCn9g==} 1891 + hasBin: true 1892 + 1893 + parse-entities@4.0.2: 1894 + resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} 1895 + 1896 + parse-latin@7.0.0: 1897 + resolution: {integrity: sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==} 1898 + 1899 + parse5@7.3.0: 1900 + resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} 1901 + 1902 + path-data-parser@0.1.0: 1903 + resolution: {integrity: sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==} 1904 + 1905 + pathe@2.0.3: 1906 + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} 1907 + 1908 + piccolore@0.1.3: 1909 + resolution: {integrity: sha512-o8bTeDWjE086iwKrROaDf31K0qC/BENdm15/uH9usSC/uZjJOKb2YGiVHfLY4GhwsERiPI1jmwI2XrA7ACOxVw==} 1910 + 1911 + picocolors@1.1.1: 1912 + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} 1913 + 1914 + picomatch@2.3.1: 1915 + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} 1916 + engines: {node: '>=8.6'} 1917 + 1918 + picomatch@4.0.3: 1919 + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} 1920 + engines: {node: '>=12'} 1921 + 1922 + pkg-types@1.3.1: 1923 + resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} 1924 + 1925 + points-on-curve@0.2.0: 1926 + resolution: {integrity: sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A==} 1927 + 1928 + points-on-path@0.2.1: 1929 + resolution: {integrity: sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g==} 1930 + 1931 + postcss-nested@6.2.0: 1932 + resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} 1933 + engines: {node: '>=12.0'} 1934 + peerDependencies: 1935 + postcss: ^8.2.14 1936 + 1937 + postcss-selector-parser@6.1.2: 1938 + resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} 1939 + engines: {node: '>=4'} 1940 + 1941 + postcss@8.5.6: 1942 + resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} 1943 + engines: {node: ^10 || ^12 || >=14} 1944 + 1945 + prismjs@1.30.0: 1946 + resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==} 1947 + engines: {node: '>=6'} 1948 + 1949 + prompts@2.4.2: 1950 + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} 1951 + engines: {node: '>= 6'} 1952 + 1953 + property-information@7.1.0: 1954 + resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} 1955 + 1956 + radix3@1.1.2: 1957 + resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==} 1958 + 1959 + readdirp@5.0.0: 1960 + resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==} 1961 + engines: {node: '>= 20.19.0'} 1962 + 1963 + recma-build-jsx@1.0.0: 1964 + resolution: {integrity: sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==} 1965 + 1966 + recma-jsx@1.0.1: 1967 + resolution: {integrity: sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w==} 1968 + peerDependencies: 1969 + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 1970 + 1971 + recma-parse@1.0.0: 1972 + resolution: {integrity: sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==} 1973 + 1974 + recma-stringify@1.0.0: 1975 + resolution: {integrity: sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==} 1976 + 1977 + regex-recursion@6.0.2: 1978 + resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==} 1979 + 1980 + regex-utilities@2.3.0: 1981 + resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==} 1982 + 1983 + regex@6.1.0: 1984 + resolution: {integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==} 1985 + 1986 + rehype-expressive-code@0.41.6: 1987 + resolution: {integrity: sha512-aBMX8kxPtjmDSFUdZlAWJkMvsQ4ZMASfee90JWIAV8tweltXLzkWC3q++43ToTelI8ac5iC0B3/S/Cl4Ql1y2g==} 1988 + 1989 + rehype-format@5.0.1: 1990 + resolution: {integrity: sha512-zvmVru9uB0josBVpr946OR8ui7nJEdzZobwLOOqHb/OOD88W0Vk2SqLwoVOj0fM6IPCCO6TaV9CvQvJMWwukFQ==} 1991 + 1992 + rehype-parse@9.0.1: 1993 + resolution: {integrity: sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==} 1994 + 1995 + rehype-raw@7.0.0: 1996 + resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==} 1997 + 1998 + rehype-recma@1.0.0: 1999 + resolution: {integrity: sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==} 2000 + 2001 + rehype-stringify@10.0.1: 2002 + resolution: {integrity: sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==} 2003 + 2004 + rehype@13.0.2: 2005 + resolution: {integrity: sha512-j31mdaRFrwFRUIlxGeuPXXKWQxet52RBQRvCmzl5eCefn/KGbomK5GMHNMsOJf55fgo3qw5tST5neDuarDYR2A==} 2006 + 2007 + remark-directive@3.0.1: 2008 + resolution: {integrity: sha512-gwglrEQEZcZYgVyG1tQuA+h58EZfq5CSULw7J90AFuCTyib1thgHPoqQ+h9iFvU6R+vnZ5oNFQR5QKgGpk741A==} 2009 + 2010 + remark-gfm@4.0.1: 2011 + resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} 2012 + 2013 + remark-mdx@3.1.1: 2014 + resolution: {integrity: sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==} 2015 + 2016 + remark-parse@11.0.0: 2017 + resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} 2018 + 2019 + remark-rehype@11.1.2: 2020 + resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==} 2021 + 2022 + remark-smartypants@3.0.2: 2023 + resolution: {integrity: sha512-ILTWeOriIluwEvPjv67v7Blgrcx+LZOkAUVtKI3putuhlZm84FnqDORNXPPm+HY3NdZOMhyDwZ1E+eZB/Df5dA==} 2024 + engines: {node: '>=16.0.0'} 2025 + 2026 + remark-stringify@11.0.0: 2027 + resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} 2028 + 2029 + retext-latin@4.0.0: 2030 + resolution: {integrity: sha512-hv9woG7Fy0M9IlRQloq/N6atV82NxLGveq+3H2WOi79dtIYWN8OaxogDm77f8YnVXJL2VD3bbqowu5E3EMhBYA==} 2031 + 2032 + retext-smartypants@6.2.0: 2033 + resolution: {integrity: sha512-kk0jOU7+zGv//kfjXEBjdIryL1Acl4i9XNkHxtM7Tm5lFiCog576fjNC9hjoR7LTKQ0DsPWy09JummSsH1uqfQ==} 2034 + 2035 + retext-stringify@4.0.0: 2036 + resolution: {integrity: sha512-rtfN/0o8kL1e+78+uxPTqu1Klt0yPzKuQ2BfWwwfgIUSayyzxpM1PJzkKt4V8803uB9qSy32MvI7Xep9khTpiA==} 2037 + 2038 + retext@9.0.0: 2039 + resolution: {integrity: sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA==} 2040 + 2041 + robust-predicates@3.0.2: 2042 + resolution: {integrity: sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==} 2043 + 2044 + rollup@4.57.1: 2045 + resolution: {integrity: sha512-oQL6lgK3e2QZeQ7gcgIkS2YZPg5slw37hYufJ3edKlfQSGGm8ICoxswK15ntSzF/a8+h7ekRy7k7oWc3BQ7y8A==} 2046 + engines: {node: '>=18.0.0', npm: '>=8.0.0'} 2047 + hasBin: true 2048 + 2049 + roughjs@4.6.6: 2050 + resolution: {integrity: sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==} 2051 + 2052 + rw@1.3.3: 2053 + resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==} 2054 + 2055 + safer-buffer@2.1.2: 2056 + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} 2057 + 2058 + sax@1.4.4: 2059 + resolution: {integrity: sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==} 2060 + engines: {node: '>=11.0.0'} 2061 + 2062 + semver@7.7.4: 2063 + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} 2064 + engines: {node: '>=10'} 2065 + hasBin: true 2066 + 2067 + sharp@0.34.5: 2068 + resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==} 2069 + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} 2070 + 2071 + shiki@3.22.0: 2072 + resolution: {integrity: sha512-LBnhsoYEe0Eou4e1VgJACes+O6S6QC0w71fCSp5Oya79inkwkm15gQ1UF6VtQ8j/taMDh79hAB49WUk8ALQW3g==} 2073 + 2074 + sisteransi@1.0.5: 2075 + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} 2076 + 2077 + sitemap@8.0.2: 2078 + resolution: {integrity: sha512-LwktpJcyZDoa0IL6KT++lQ53pbSrx2c9ge41/SeLTyqy2XUNA6uR4+P9u5IVo5lPeL2arAcOKn1aZAxoYbCKlQ==} 2079 + engines: {node: '>=14.0.0', npm: '>=6.0.0'} 2080 + hasBin: true 2081 + 2082 + smol-toml@1.6.0: 2083 + resolution: {integrity: sha512-4zemZi0HvTnYwLfrpk/CF9LOd9Lt87kAt50GnqhMpyF9U3poDAP2+iukq2bZsO/ufegbYehBkqINbsWxj4l4cw==} 2084 + engines: {node: '>= 18'} 2085 + 2086 + source-map-js@1.2.1: 2087 + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} 2088 + engines: {node: '>=0.10.0'} 2089 + 2090 + source-map@0.7.6: 2091 + resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} 2092 + engines: {node: '>= 12'} 2093 + 2094 + space-separated-tokens@2.0.2: 2095 + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} 2096 + 2097 + stream-replace-string@2.0.0: 2098 + resolution: {integrity: sha512-TlnjJ1C0QrmxRNrON00JvaFFlNh5TTG00APw23j74ET7gkQpTASi6/L2fuiav8pzK715HXtUeClpBTw2NPSn6w==} 2099 + 2100 + string-width@4.2.3: 2101 + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} 2102 + engines: {node: '>=8'} 2103 + 2104 + string-width@7.2.0: 2105 + resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} 2106 + engines: {node: '>=18'} 2107 + 2108 + stringify-entities@4.0.4: 2109 + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} 2110 + 2111 + strip-ansi@6.0.1: 2112 + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} 2113 + engines: {node: '>=8'} 2114 + 2115 + strip-ansi@7.1.2: 2116 + resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} 2117 + engines: {node: '>=12'} 2118 + 2119 + style-to-js@1.1.21: 2120 + resolution: {integrity: sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==} 2121 + 2122 + style-to-object@1.0.14: 2123 + resolution: {integrity: sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==} 2124 + 2125 + stylis@4.3.6: 2126 + resolution: {integrity: sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==} 2127 + 2128 + svgo@4.0.0: 2129 + resolution: {integrity: sha512-VvrHQ+9uniE+Mvx3+C9IEe/lWasXCU0nXMY2kZeLrHNICuRiC8uMPyM14UEaMOFA5mhyQqEkB02VoQ16n3DLaw==} 2130 + engines: {node: '>=16'} 2131 + hasBin: true 2132 + 2133 + tiny-inflate@1.0.3: 2134 + resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==} 2135 + 2136 + tinyexec@1.0.2: 2137 + resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} 2138 + engines: {node: '>=18'} 2139 + 2140 + tinyglobby@0.2.15: 2141 + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} 2142 + engines: {node: '>=12.0.0'} 2143 + 2144 + trim-lines@3.0.1: 2145 + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} 2146 + 2147 + trough@2.2.0: 2148 + resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} 2149 + 2150 + ts-dedent@2.2.0: 2151 + resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==} 2152 + engines: {node: '>=6.10'} 2153 + 2154 + tsconfck@3.1.6: 2155 + resolution: {integrity: sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==} 2156 + engines: {node: ^18 || >=20} 2157 + hasBin: true 2158 + peerDependencies: 2159 + typescript: ^5.0.0 2160 + peerDependenciesMeta: 2161 + typescript: 2162 + optional: true 2163 + 2164 + tslib@2.8.1: 2165 + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} 2166 + 2167 + type-fest@4.41.0: 2168 + resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} 2169 + engines: {node: '>=16'} 2170 + 2171 + typescript@5.9.3: 2172 + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} 2173 + engines: {node: '>=14.17'} 2174 + hasBin: true 2175 + 2176 + ufo@1.6.3: 2177 + resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==} 2178 + 2179 + ultrahtml@1.6.0: 2180 + resolution: {integrity: sha512-R9fBn90VTJrqqLDwyMph+HGne8eqY1iPfYhPzZrvKpIfwkWZbcYlfpsb8B9dTvBfpy1/hqAD7Wi8EKfP9e8zdw==} 2181 + 2182 + uncrypto@0.1.3: 2183 + resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} 2184 + 2185 + unified@11.0.5: 2186 + resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} 2187 + 2188 + unifont@0.7.4: 2189 + resolution: {integrity: sha512-oHeis4/xl42HUIeHuNZRGEvxj5AaIKR+bHPNegRq5LV1gdc3jundpONbjglKpihmJf+dswygdMJn3eftGIMemg==} 2190 + 2191 + unist-util-find-after@5.0.0: 2192 + resolution: {integrity: sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==} 2193 + 2194 + unist-util-is@6.0.1: 2195 + resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} 2196 + 2197 + unist-util-modify-children@4.0.0: 2198 + resolution: {integrity: sha512-+tdN5fGNddvsQdIzUF3Xx82CU9sMM+fA0dLgR9vOmT0oPT2jH+P1nd5lSqfCfXAw+93NhcXNY2qqvTUtE4cQkw==} 2199 + 2200 + unist-util-position-from-estree@2.0.0: 2201 + resolution: {integrity: sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==} 2202 + 2203 + unist-util-position@5.0.0: 2204 + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} 2205 + 2206 + unist-util-remove-position@5.0.0: 2207 + resolution: {integrity: sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==} 2208 + 2209 + unist-util-stringify-position@4.0.0: 2210 + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} 2211 + 2212 + unist-util-visit-children@3.0.0: 2213 + resolution: {integrity: sha512-RgmdTfSBOg04sdPcpTSD1jzoNBjt9a80/ZCzp5cI9n1qPzLZWF9YdvWGN2zmTumP1HWhXKdUWexjy/Wy/lJ7tA==} 2214 + 2215 + unist-util-visit-parents@6.0.2: 2216 + resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} 2217 + 2218 + unist-util-visit@5.1.0: 2219 + resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==} 2220 + 2221 + unstorage@1.17.4: 2222 + resolution: {integrity: sha512-fHK0yNg38tBiJKp/Vgsq4j0JEsCmgqH58HAn707S7zGkArbZsVr/CwINoi+nh3h98BRCwKvx1K3Xg9u3VV83sw==} 2223 + peerDependencies: 2224 + '@azure/app-configuration': ^1.8.0 2225 + '@azure/cosmos': ^4.2.0 2226 + '@azure/data-tables': ^13.3.0 2227 + '@azure/identity': ^4.6.0 2228 + '@azure/keyvault-secrets': ^4.9.0 2229 + '@azure/storage-blob': ^12.26.0 2230 + '@capacitor/preferences': ^6 || ^7 || ^8 2231 + '@deno/kv': '>=0.9.0' 2232 + '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0 2233 + '@planetscale/database': ^1.19.0 2234 + '@upstash/redis': ^1.34.3 2235 + '@vercel/blob': '>=0.27.1' 2236 + '@vercel/functions': ^2.2.12 || ^3.0.0 2237 + '@vercel/kv': ^1 || ^2 || ^3 2238 + aws4fetch: ^1.0.20 2239 + db0: '>=0.2.1' 2240 + idb-keyval: ^6.2.1 2241 + ioredis: ^5.4.2 2242 + uploadthing: ^7.4.4 2243 + peerDependenciesMeta: 2244 + '@azure/app-configuration': 2245 + optional: true 2246 + '@azure/cosmos': 2247 + optional: true 2248 + '@azure/data-tables': 2249 + optional: true 2250 + '@azure/identity': 2251 + optional: true 2252 + '@azure/keyvault-secrets': 2253 + optional: true 2254 + '@azure/storage-blob': 2255 + optional: true 2256 + '@capacitor/preferences': 2257 + optional: true 2258 + '@deno/kv': 2259 + optional: true 2260 + '@netlify/blobs': 2261 + optional: true 2262 + '@planetscale/database': 2263 + optional: true 2264 + '@upstash/redis': 2265 + optional: true 2266 + '@vercel/blob': 2267 + optional: true 2268 + '@vercel/functions': 2269 + optional: true 2270 + '@vercel/kv': 2271 + optional: true 2272 + aws4fetch: 2273 + optional: true 2274 + db0: 2275 + optional: true 2276 + idb-keyval: 2277 + optional: true 2278 + ioredis: 2279 + optional: true 2280 + uploadthing: 2281 + optional: true 2282 + 2283 + util-deprecate@1.0.2: 2284 + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} 2285 + 2286 + uuid@11.1.0: 2287 + resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} 2288 + hasBin: true 2289 + 2290 + vfile-location@5.0.3: 2291 + resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==} 2292 + 2293 + vfile-message@4.0.3: 2294 + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} 2295 + 2296 + vfile@6.0.3: 2297 + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} 2298 + 2299 + vite@6.4.1: 2300 + resolution: {integrity: sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==} 2301 + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} 2302 + hasBin: true 2303 + peerDependencies: 2304 + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 2305 + jiti: '>=1.21.0' 2306 + less: '*' 2307 + lightningcss: ^1.21.0 2308 + sass: '*' 2309 + sass-embedded: '*' 2310 + stylus: '*' 2311 + sugarss: '*' 2312 + terser: ^5.16.0 2313 + tsx: ^4.8.1 2314 + yaml: ^2.4.2 2315 + peerDependenciesMeta: 2316 + '@types/node': 2317 + optional: true 2318 + jiti: 2319 + optional: true 2320 + less: 2321 + optional: true 2322 + lightningcss: 2323 + optional: true 2324 + sass: 2325 + optional: true 2326 + sass-embedded: 2327 + optional: true 2328 + stylus: 2329 + optional: true 2330 + sugarss: 2331 + optional: true 2332 + terser: 2333 + optional: true 2334 + tsx: 2335 + optional: true 2336 + yaml: 2337 + optional: true 2338 + 2339 + vitefu@1.1.1: 2340 + resolution: {integrity: sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==} 2341 + peerDependencies: 2342 + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0 2343 + peerDependenciesMeta: 2344 + vite: 2345 + optional: true 2346 + 2347 + vscode-jsonrpc@8.2.0: 2348 + resolution: {integrity: sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==} 2349 + engines: {node: '>=14.0.0'} 2350 + 2351 + vscode-languageserver-protocol@3.17.5: 2352 + resolution: {integrity: sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==} 2353 + 2354 + vscode-languageserver-textdocument@1.0.12: 2355 + resolution: {integrity: sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==} 2356 + 2357 + vscode-languageserver-types@3.17.5: 2358 + resolution: {integrity: sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==} 2359 + 2360 + vscode-languageserver@9.0.1: 2361 + resolution: {integrity: sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==} 2362 + hasBin: true 2363 + 2364 + vscode-uri@3.1.0: 2365 + resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==} 2366 + 2367 + web-namespaces@2.0.1: 2368 + resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} 2369 + 2370 + which-pm-runs@1.1.0: 2371 + resolution: {integrity: sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==} 2372 + engines: {node: '>=4'} 2373 + 2374 + widest-line@5.0.0: 2375 + resolution: {integrity: sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==} 2376 + engines: {node: '>=18'} 2377 + 2378 + wrap-ansi@9.0.2: 2379 + resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==} 2380 + engines: {node: '>=18'} 2381 + 2382 + xxhash-wasm@1.1.0: 2383 + resolution: {integrity: sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==} 2384 + 2385 + yargs-parser@21.1.1: 2386 + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} 2387 + engines: {node: '>=12'} 2388 + 2389 + yocto-queue@1.2.2: 2390 + resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==} 2391 + engines: {node: '>=12.20'} 2392 + 2393 + yocto-spinner@0.2.3: 2394 + resolution: {integrity: sha512-sqBChb33loEnkoXte1bLg45bEBsOP9N1kzQh5JZNKj/0rik4zAPTNSAVPj3uQAdc6slYJ0Ksc403G2XgxsJQFQ==} 2395 + engines: {node: '>=18.19'} 2396 + 2397 + yoctocolors@2.1.2: 2398 + resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==} 2399 + engines: {node: '>=18'} 2400 + 2401 + zod-to-json-schema@3.25.1: 2402 + resolution: {integrity: sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==} 2403 + peerDependencies: 2404 + zod: ^3.25 || ^4 2405 + 2406 + zod-to-ts@1.2.0: 2407 + resolution: {integrity: sha512-x30XE43V+InwGpvTySRNz9kB7qFU8DlyEy7BsSTCHPH1R0QasMmHWZDCzYm6bVXtj/9NNJAZF3jW8rzFvH5OFA==} 2408 + peerDependencies: 2409 + typescript: ^4.9.4 || ^5.0.2 2410 + zod: ^3 2411 + 2412 + zod@3.25.76: 2413 + resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} 2414 + 2415 + zwitch@2.0.4: 2416 + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} 2417 + 2418 + snapshots: 2419 + 2420 + '@antfu/install-pkg@1.1.0': 2421 + dependencies: 2422 + package-manager-detector: 1.6.0 2423 + tinyexec: 1.0.2 2424 + 2425 + '@astrojs/compiler@2.13.1': {} 2426 + 2427 + '@astrojs/internal-helpers@0.7.5': {} 2428 + 2429 + '@astrojs/markdown-remark@6.3.10': 2430 + dependencies: 2431 + '@astrojs/internal-helpers': 0.7.5 2432 + '@astrojs/prism': 3.3.0 2433 + github-slugger: 2.0.0 2434 + hast-util-from-html: 2.0.3 2435 + hast-util-to-text: 4.0.2 2436 + import-meta-resolve: 4.2.0 2437 + js-yaml: 4.1.1 2438 + mdast-util-definitions: 6.0.0 2439 + rehype-raw: 7.0.0 2440 + rehype-stringify: 10.0.1 2441 + remark-gfm: 4.0.1 2442 + remark-parse: 11.0.0 2443 + remark-rehype: 11.1.2 2444 + remark-smartypants: 3.0.2 2445 + shiki: 3.22.0 2446 + smol-toml: 1.6.0 2447 + unified: 11.0.5 2448 + unist-util-remove-position: 5.0.0 2449 + unist-util-visit: 5.1.0 2450 + unist-util-visit-parents: 6.0.2 2451 + vfile: 6.0.3 2452 + transitivePeerDependencies: 2453 + - supports-color 2454 + 2455 + '@astrojs/mdx@4.3.13(astro@5.17.3(rollup@4.57.1)(typescript@5.9.3))': 2456 + dependencies: 2457 + '@astrojs/markdown-remark': 6.3.10 2458 + '@mdx-js/mdx': 3.1.1 2459 + acorn: 8.16.0 2460 + astro: 5.17.3(rollup@4.57.1)(typescript@5.9.3) 2461 + es-module-lexer: 1.7.0 2462 + estree-util-visit: 2.0.0 2463 + hast-util-to-html: 9.0.5 2464 + piccolore: 0.1.3 2465 + rehype-raw: 7.0.0 2466 + remark-gfm: 4.0.1 2467 + remark-smartypants: 3.0.2 2468 + source-map: 0.7.6 2469 + unist-util-visit: 5.1.0 2470 + vfile: 6.0.3 2471 + transitivePeerDependencies: 2472 + - supports-color 2473 + 2474 + '@astrojs/prism@3.3.0': 2475 + dependencies: 2476 + prismjs: 1.30.0 2477 + 2478 + '@astrojs/sitemap@3.7.0': 2479 + dependencies: 2480 + sitemap: 8.0.2 2481 + stream-replace-string: 2.0.0 2482 + zod: 3.25.76 2483 + 2484 + '@astrojs/starlight@0.37.6(astro@5.17.3(rollup@4.57.1)(typescript@5.9.3))': 2485 + dependencies: 2486 + '@astrojs/markdown-remark': 6.3.10 2487 + '@astrojs/mdx': 4.3.13(astro@5.17.3(rollup@4.57.1)(typescript@5.9.3)) 2488 + '@astrojs/sitemap': 3.7.0 2489 + '@pagefind/default-ui': 1.4.0 2490 + '@types/hast': 3.0.4 2491 + '@types/js-yaml': 4.0.9 2492 + '@types/mdast': 4.0.4 2493 + astro: 5.17.3(rollup@4.57.1)(typescript@5.9.3) 2494 + astro-expressive-code: 0.41.6(astro@5.17.3(rollup@4.57.1)(typescript@5.9.3)) 2495 + bcp-47: 2.1.0 2496 + hast-util-from-html: 2.0.3 2497 + hast-util-select: 6.0.4 2498 + hast-util-to-string: 3.0.1 2499 + hastscript: 9.0.1 2500 + i18next: 23.16.8 2501 + js-yaml: 4.1.1 2502 + klona: 2.0.6 2503 + magic-string: 0.30.21 2504 + mdast-util-directive: 3.1.0 2505 + mdast-util-to-markdown: 2.1.2 2506 + mdast-util-to-string: 4.0.0 2507 + pagefind: 1.4.0 2508 + rehype: 13.0.2 2509 + rehype-format: 5.0.1 2510 + remark-directive: 3.0.1 2511 + ultrahtml: 1.6.0 2512 + unified: 11.0.5 2513 + unist-util-visit: 5.1.0 2514 + vfile: 6.0.3 2515 + transitivePeerDependencies: 2516 + - supports-color 2517 + 2518 + '@astrojs/telemetry@3.3.0': 2519 + dependencies: 2520 + ci-info: 4.4.0 2521 + debug: 4.4.3 2522 + dlv: 1.1.3 2523 + dset: 3.1.4 2524 + is-docker: 3.0.0 2525 + is-wsl: 3.1.1 2526 + which-pm-runs: 1.1.0 2527 + transitivePeerDependencies: 2528 + - supports-color 2529 + 2530 + '@babel/helper-string-parser@7.27.1': {} 2531 + 2532 + '@babel/helper-validator-identifier@7.28.5': {} 2533 + 2534 + '@babel/parser@7.29.0': 2535 + dependencies: 2536 + '@babel/types': 7.29.0 2537 + 2538 + '@babel/runtime@7.28.6': {} 2539 + 2540 + '@babel/types@7.29.0': 2541 + dependencies: 2542 + '@babel/helper-string-parser': 7.27.1 2543 + '@babel/helper-validator-identifier': 7.28.5 2544 + 2545 + '@braintree/sanitize-url@7.1.2': {} 2546 + 2547 + '@capsizecss/unpack@4.0.0': 2548 + dependencies: 2549 + fontkitten: 1.0.2 2550 + 2551 + '@catppuccin/starlight@1.1.1(@astrojs/starlight@0.37.6(astro@5.17.3(rollup@4.57.1)(typescript@5.9.3)))(astro@5.17.3(rollup@4.57.1)(typescript@5.9.3))': 2552 + dependencies: 2553 + '@astrojs/starlight': 0.37.6(astro@5.17.3(rollup@4.57.1)(typescript@5.9.3)) 2554 + astro: 5.17.3(rollup@4.57.1)(typescript@5.9.3) 2555 + 2556 + '@chevrotain/cst-dts-gen@11.1.1': 2557 + dependencies: 2558 + '@chevrotain/gast': 11.1.1 2559 + '@chevrotain/types': 11.1.1 2560 + lodash-es: 4.17.23 2561 + 2562 + '@chevrotain/gast@11.1.1': 2563 + dependencies: 2564 + '@chevrotain/types': 11.1.1 2565 + lodash-es: 4.17.23 2566 + 2567 + '@chevrotain/regexp-to-ast@11.1.1': {} 2568 + 2569 + '@chevrotain/types@11.1.1': {} 2570 + 2571 + '@chevrotain/utils@11.1.1': {} 2572 + 2573 + '@ctrl/tinycolor@4.2.0': {} 2574 + 2575 + '@emnapi/runtime@1.8.1': 2576 + dependencies: 2577 + tslib: 2.8.1 2578 + optional: true 2579 + 2580 + '@esbuild/aix-ppc64@0.25.12': 2581 + optional: true 2582 + 2583 + '@esbuild/aix-ppc64@0.27.3': 2584 + optional: true 2585 + 2586 + '@esbuild/android-arm64@0.25.12': 2587 + optional: true 2588 + 2589 + '@esbuild/android-arm64@0.27.3': 2590 + optional: true 2591 + 2592 + '@esbuild/android-arm@0.25.12': 2593 + optional: true 2594 + 2595 + '@esbuild/android-arm@0.27.3': 2596 + optional: true 2597 + 2598 + '@esbuild/android-x64@0.25.12': 2599 + optional: true 2600 + 2601 + '@esbuild/android-x64@0.27.3': 2602 + optional: true 2603 + 2604 + '@esbuild/darwin-arm64@0.25.12': 2605 + optional: true 2606 + 2607 + '@esbuild/darwin-arm64@0.27.3': 2608 + optional: true 2609 + 2610 + '@esbuild/darwin-x64@0.25.12': 2611 + optional: true 2612 + 2613 + '@esbuild/darwin-x64@0.27.3': 2614 + optional: true 2615 + 2616 + '@esbuild/freebsd-arm64@0.25.12': 2617 + optional: true 2618 + 2619 + '@esbuild/freebsd-arm64@0.27.3': 2620 + optional: true 2621 + 2622 + '@esbuild/freebsd-x64@0.25.12': 2623 + optional: true 2624 + 2625 + '@esbuild/freebsd-x64@0.27.3': 2626 + optional: true 2627 + 2628 + '@esbuild/linux-arm64@0.25.12': 2629 + optional: true 2630 + 2631 + '@esbuild/linux-arm64@0.27.3': 2632 + optional: true 2633 + 2634 + '@esbuild/linux-arm@0.25.12': 2635 + optional: true 2636 + 2637 + '@esbuild/linux-arm@0.27.3': 2638 + optional: true 2639 + 2640 + '@esbuild/linux-ia32@0.25.12': 2641 + optional: true 2642 + 2643 + '@esbuild/linux-ia32@0.27.3': 2644 + optional: true 2645 + 2646 + '@esbuild/linux-loong64@0.25.12': 2647 + optional: true 2648 + 2649 + '@esbuild/linux-loong64@0.27.3': 2650 + optional: true 2651 + 2652 + '@esbuild/linux-mips64el@0.25.12': 2653 + optional: true 2654 + 2655 + '@esbuild/linux-mips64el@0.27.3': 2656 + optional: true 2657 + 2658 + '@esbuild/linux-ppc64@0.25.12': 2659 + optional: true 2660 + 2661 + '@esbuild/linux-ppc64@0.27.3': 2662 + optional: true 2663 + 2664 + '@esbuild/linux-riscv64@0.25.12': 2665 + optional: true 2666 + 2667 + '@esbuild/linux-riscv64@0.27.3': 2668 + optional: true 2669 + 2670 + '@esbuild/linux-s390x@0.25.12': 2671 + optional: true 2672 + 2673 + '@esbuild/linux-s390x@0.27.3': 2674 + optional: true 2675 + 2676 + '@esbuild/linux-x64@0.25.12': 2677 + optional: true 2678 + 2679 + '@esbuild/linux-x64@0.27.3': 2680 + optional: true 2681 + 2682 + '@esbuild/netbsd-arm64@0.25.12': 2683 + optional: true 2684 + 2685 + '@esbuild/netbsd-arm64@0.27.3': 2686 + optional: true 2687 + 2688 + '@esbuild/netbsd-x64@0.25.12': 2689 + optional: true 2690 + 2691 + '@esbuild/netbsd-x64@0.27.3': 2692 + optional: true 2693 + 2694 + '@esbuild/openbsd-arm64@0.25.12': 2695 + optional: true 2696 + 2697 + '@esbuild/openbsd-arm64@0.27.3': 2698 + optional: true 2699 + 2700 + '@esbuild/openbsd-x64@0.25.12': 2701 + optional: true 2702 + 2703 + '@esbuild/openbsd-x64@0.27.3': 2704 + optional: true 2705 + 2706 + '@esbuild/openharmony-arm64@0.25.12': 2707 + optional: true 2708 + 2709 + '@esbuild/openharmony-arm64@0.27.3': 2710 + optional: true 2711 + 2712 + '@esbuild/sunos-x64@0.25.12': 2713 + optional: true 2714 + 2715 + '@esbuild/sunos-x64@0.27.3': 2716 + optional: true 2717 + 2718 + '@esbuild/win32-arm64@0.25.12': 2719 + optional: true 2720 + 2721 + '@esbuild/win32-arm64@0.27.3': 2722 + optional: true 2723 + 2724 + '@esbuild/win32-ia32@0.25.12': 2725 + optional: true 2726 + 2727 + '@esbuild/win32-ia32@0.27.3': 2728 + optional: true 2729 + 2730 + '@esbuild/win32-x64@0.25.12': 2731 + optional: true 2732 + 2733 + '@esbuild/win32-x64@0.27.3': 2734 + optional: true 2735 + 2736 + '@expressive-code/core@0.41.6': 2737 + dependencies: 2738 + '@ctrl/tinycolor': 4.2.0 2739 + hast-util-select: 6.0.4 2740 + hast-util-to-html: 9.0.5 2741 + hast-util-to-text: 4.0.2 2742 + hastscript: 9.0.1 2743 + postcss: 8.5.6 2744 + postcss-nested: 6.2.0(postcss@8.5.6) 2745 + unist-util-visit: 5.1.0 2746 + unist-util-visit-parents: 6.0.2 2747 + 2748 + '@expressive-code/plugin-frames@0.41.6': 2749 + dependencies: 2750 + '@expressive-code/core': 0.41.6 2751 + 2752 + '@expressive-code/plugin-shiki@0.41.6': 2753 + dependencies: 2754 + '@expressive-code/core': 0.41.6 2755 + shiki: 3.22.0 2756 + 2757 + '@expressive-code/plugin-text-markers@0.41.6': 2758 + dependencies: 2759 + '@expressive-code/core': 0.41.6 2760 + 2761 + '@iconify/types@2.0.0': {} 2762 + 2763 + '@iconify/utils@3.1.0': 2764 + dependencies: 2765 + '@antfu/install-pkg': 1.1.0 2766 + '@iconify/types': 2.0.0 2767 + mlly: 1.8.0 2768 + 2769 + '@img/colour@1.0.0': {} 2770 + 2771 + '@img/sharp-darwin-arm64@0.34.5': 2772 + optionalDependencies: 2773 + '@img/sharp-libvips-darwin-arm64': 1.2.4 2774 + optional: true 2775 + 2776 + '@img/sharp-darwin-x64@0.34.5': 2777 + optionalDependencies: 2778 + '@img/sharp-libvips-darwin-x64': 1.2.4 2779 + optional: true 2780 + 2781 + '@img/sharp-libvips-darwin-arm64@1.2.4': 2782 + optional: true 2783 + 2784 + '@img/sharp-libvips-darwin-x64@1.2.4': 2785 + optional: true 2786 + 2787 + '@img/sharp-libvips-linux-arm64@1.2.4': 2788 + optional: true 2789 + 2790 + '@img/sharp-libvips-linux-arm@1.2.4': 2791 + optional: true 2792 + 2793 + '@img/sharp-libvips-linux-ppc64@1.2.4': 2794 + optional: true 2795 + 2796 + '@img/sharp-libvips-linux-riscv64@1.2.4': 2797 + optional: true 2798 + 2799 + '@img/sharp-libvips-linux-s390x@1.2.4': 2800 + optional: true 2801 + 2802 + '@img/sharp-libvips-linux-x64@1.2.4': 2803 + optional: true 2804 + 2805 + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': 2806 + optional: true 2807 + 2808 + '@img/sharp-libvips-linuxmusl-x64@1.2.4': 2809 + optional: true 2810 + 2811 + '@img/sharp-linux-arm64@0.34.5': 2812 + optionalDependencies: 2813 + '@img/sharp-libvips-linux-arm64': 1.2.4 2814 + optional: true 2815 + 2816 + '@img/sharp-linux-arm@0.34.5': 2817 + optionalDependencies: 2818 + '@img/sharp-libvips-linux-arm': 1.2.4 2819 + optional: true 2820 + 2821 + '@img/sharp-linux-ppc64@0.34.5': 2822 + optionalDependencies: 2823 + '@img/sharp-libvips-linux-ppc64': 1.2.4 2824 + optional: true 2825 + 2826 + '@img/sharp-linux-riscv64@0.34.5': 2827 + optionalDependencies: 2828 + '@img/sharp-libvips-linux-riscv64': 1.2.4 2829 + optional: true 2830 + 2831 + '@img/sharp-linux-s390x@0.34.5': 2832 + optionalDependencies: 2833 + '@img/sharp-libvips-linux-s390x': 1.2.4 2834 + optional: true 2835 + 2836 + '@img/sharp-linux-x64@0.34.5': 2837 + optionalDependencies: 2838 + '@img/sharp-libvips-linux-x64': 1.2.4 2839 + optional: true 2840 + 2841 + '@img/sharp-linuxmusl-arm64@0.34.5': 2842 + optionalDependencies: 2843 + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 2844 + optional: true 2845 + 2846 + '@img/sharp-linuxmusl-x64@0.34.5': 2847 + optionalDependencies: 2848 + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 2849 + optional: true 2850 + 2851 + '@img/sharp-wasm32@0.34.5': 2852 + dependencies: 2853 + '@emnapi/runtime': 1.8.1 2854 + optional: true 2855 + 2856 + '@img/sharp-win32-arm64@0.34.5': 2857 + optional: true 2858 + 2859 + '@img/sharp-win32-ia32@0.34.5': 2860 + optional: true 2861 + 2862 + '@img/sharp-win32-x64@0.34.5': 2863 + optional: true 2864 + 2865 + '@jridgewell/sourcemap-codec@1.5.5': {} 2866 + 2867 + '@mdx-js/mdx@3.1.1': 2868 + dependencies: 2869 + '@types/estree': 1.0.8 2870 + '@types/estree-jsx': 1.0.5 2871 + '@types/hast': 3.0.4 2872 + '@types/mdx': 2.0.13 2873 + acorn: 8.16.0 2874 + collapse-white-space: 2.1.0 2875 + devlop: 1.1.0 2876 + estree-util-is-identifier-name: 3.0.0 2877 + estree-util-scope: 1.0.0 2878 + estree-walker: 3.0.3 2879 + hast-util-to-jsx-runtime: 2.3.6 2880 + markdown-extensions: 2.0.0 2881 + recma-build-jsx: 1.0.0 2882 + recma-jsx: 1.0.1(acorn@8.16.0) 2883 + recma-stringify: 1.0.0 2884 + rehype-recma: 1.0.0 2885 + remark-mdx: 3.1.1 2886 + remark-parse: 11.0.0 2887 + remark-rehype: 11.1.2 2888 + source-map: 0.7.6 2889 + unified: 11.0.5 2890 + unist-util-position-from-estree: 2.0.0 2891 + unist-util-stringify-position: 4.0.0 2892 + unist-util-visit: 5.1.0 2893 + vfile: 6.0.3 2894 + transitivePeerDependencies: 2895 + - supports-color 2896 + 2897 + '@mermaid-js/parser@1.0.0': 2898 + dependencies: 2899 + langium: 4.2.1 2900 + 2901 + '@oslojs/encoding@1.1.0': {} 2902 + 2903 + '@pagefind/darwin-arm64@1.4.0': 2904 + optional: true 2905 + 2906 + '@pagefind/darwin-x64@1.4.0': 2907 + optional: true 2908 + 2909 + '@pagefind/default-ui@1.4.0': {} 2910 + 2911 + '@pagefind/freebsd-x64@1.4.0': 2912 + optional: true 2913 + 2914 + '@pagefind/linux-arm64@1.4.0': 2915 + optional: true 2916 + 2917 + '@pagefind/linux-x64@1.4.0': 2918 + optional: true 2919 + 2920 + '@pagefind/windows-x64@1.4.0': 2921 + optional: true 2922 + 2923 + '@rollup/pluginutils@5.3.0(rollup@4.57.1)': 2924 + dependencies: 2925 + '@types/estree': 1.0.8 2926 + estree-walker: 2.0.2 2927 + picomatch: 4.0.3 2928 + optionalDependencies: 2929 + rollup: 4.57.1 2930 + 2931 + '@rollup/rollup-android-arm-eabi@4.57.1': 2932 + optional: true 2933 + 2934 + '@rollup/rollup-android-arm64@4.57.1': 2935 + optional: true 2936 + 2937 + '@rollup/rollup-darwin-arm64@4.57.1': 2938 + optional: true 2939 + 2940 + '@rollup/rollup-darwin-x64@4.57.1': 2941 + optional: true 2942 + 2943 + '@rollup/rollup-freebsd-arm64@4.57.1': 2944 + optional: true 2945 + 2946 + '@rollup/rollup-freebsd-x64@4.57.1': 2947 + optional: true 2948 + 2949 + '@rollup/rollup-linux-arm-gnueabihf@4.57.1': 2950 + optional: true 2951 + 2952 + '@rollup/rollup-linux-arm-musleabihf@4.57.1': 2953 + optional: true 2954 + 2955 + '@rollup/rollup-linux-arm64-gnu@4.57.1': 2956 + optional: true 2957 + 2958 + '@rollup/rollup-linux-arm64-musl@4.57.1': 2959 + optional: true 2960 + 2961 + '@rollup/rollup-linux-loong64-gnu@4.57.1': 2962 + optional: true 2963 + 2964 + '@rollup/rollup-linux-loong64-musl@4.57.1': 2965 + optional: true 2966 + 2967 + '@rollup/rollup-linux-ppc64-gnu@4.57.1': 2968 + optional: true 2969 + 2970 + '@rollup/rollup-linux-ppc64-musl@4.57.1': 2971 + optional: true 2972 + 2973 + '@rollup/rollup-linux-riscv64-gnu@4.57.1': 2974 + optional: true 2975 + 2976 + '@rollup/rollup-linux-riscv64-musl@4.57.1': 2977 + optional: true 2978 + 2979 + '@rollup/rollup-linux-s390x-gnu@4.57.1': 2980 + optional: true 2981 + 2982 + '@rollup/rollup-linux-x64-gnu@4.57.1': 2983 + optional: true 2984 + 2985 + '@rollup/rollup-linux-x64-musl@4.57.1': 2986 + optional: true 2987 + 2988 + '@rollup/rollup-openbsd-x64@4.57.1': 2989 + optional: true 2990 + 2991 + '@rollup/rollup-openharmony-arm64@4.57.1': 2992 + optional: true 2993 + 2994 + '@rollup/rollup-win32-arm64-msvc@4.57.1': 2995 + optional: true 2996 + 2997 + '@rollup/rollup-win32-ia32-msvc@4.57.1': 2998 + optional: true 2999 + 3000 + '@rollup/rollup-win32-x64-gnu@4.57.1': 3001 + optional: true 3002 + 3003 + '@rollup/rollup-win32-x64-msvc@4.57.1': 3004 + optional: true 3005 + 3006 + '@shikijs/core@3.22.0': 3007 + dependencies: 3008 + '@shikijs/types': 3.22.0 3009 + '@shikijs/vscode-textmate': 10.0.2 3010 + '@types/hast': 3.0.4 3011 + hast-util-to-html: 9.0.5 3012 + 3013 + '@shikijs/engine-javascript@3.22.0': 3014 + dependencies: 3015 + '@shikijs/types': 3.22.0 3016 + '@shikijs/vscode-textmate': 10.0.2 3017 + oniguruma-to-es: 4.3.4 3018 + 3019 + '@shikijs/engine-oniguruma@3.22.0': 3020 + dependencies: 3021 + '@shikijs/types': 3.22.0 3022 + '@shikijs/vscode-textmate': 10.0.2 3023 + 3024 + '@shikijs/langs@3.22.0': 3025 + dependencies: 3026 + '@shikijs/types': 3.22.0 3027 + 3028 + '@shikijs/themes@3.22.0': 3029 + dependencies: 3030 + '@shikijs/types': 3.22.0 3031 + 3032 + '@shikijs/types@3.22.0': 3033 + dependencies: 3034 + '@shikijs/vscode-textmate': 10.0.2 3035 + '@types/hast': 3.0.4 3036 + 3037 + '@shikijs/vscode-textmate@10.0.2': {} 3038 + 3039 + '@types/d3-array@3.2.2': {} 3040 + 3041 + '@types/d3-axis@3.0.6': 3042 + dependencies: 3043 + '@types/d3-selection': 3.0.11 3044 + 3045 + '@types/d3-brush@3.0.6': 3046 + dependencies: 3047 + '@types/d3-selection': 3.0.11 3048 + 3049 + '@types/d3-chord@3.0.6': {} 3050 + 3051 + '@types/d3-color@3.1.3': {} 3052 + 3053 + '@types/d3-contour@3.0.6': 3054 + dependencies: 3055 + '@types/d3-array': 3.2.2 3056 + '@types/geojson': 7946.0.16 3057 + 3058 + '@types/d3-delaunay@6.0.4': {} 3059 + 3060 + '@types/d3-dispatch@3.0.7': {} 3061 + 3062 + '@types/d3-drag@3.0.7': 3063 + dependencies: 3064 + '@types/d3-selection': 3.0.11 3065 + 3066 + '@types/d3-dsv@3.0.7': {} 3067 + 3068 + '@types/d3-ease@3.0.2': {} 3069 + 3070 + '@types/d3-fetch@3.0.7': 3071 + dependencies: 3072 + '@types/d3-dsv': 3.0.7 3073 + 3074 + '@types/d3-force@3.0.10': {} 3075 + 3076 + '@types/d3-format@3.0.4': {} 3077 + 3078 + '@types/d3-geo@3.1.0': 3079 + dependencies: 3080 + '@types/geojson': 7946.0.16 3081 + 3082 + '@types/d3-hierarchy@3.1.7': {} 3083 + 3084 + '@types/d3-interpolate@3.0.4': 3085 + dependencies: 3086 + '@types/d3-color': 3.1.3 3087 + 3088 + '@types/d3-path@3.1.1': {} 3089 + 3090 + '@types/d3-polygon@3.0.2': {} 3091 + 3092 + '@types/d3-quadtree@3.0.6': {} 3093 + 3094 + '@types/d3-random@3.0.3': {} 3095 + 3096 + '@types/d3-scale-chromatic@3.1.0': {} 3097 + 3098 + '@types/d3-scale@4.0.9': 3099 + dependencies: 3100 + '@types/d3-time': 3.0.4 3101 + 3102 + '@types/d3-selection@3.0.11': {} 3103 + 3104 + '@types/d3-shape@3.1.8': 3105 + dependencies: 3106 + '@types/d3-path': 3.1.1 3107 + 3108 + '@types/d3-time-format@4.0.3': {} 3109 + 3110 + '@types/d3-time@3.0.4': {} 3111 + 3112 + '@types/d3-timer@3.0.2': {} 3113 + 3114 + '@types/d3-transition@3.0.9': 3115 + dependencies: 3116 + '@types/d3-selection': 3.0.11 3117 + 3118 + '@types/d3-zoom@3.0.8': 3119 + dependencies: 3120 + '@types/d3-interpolate': 3.0.4 3121 + '@types/d3-selection': 3.0.11 3122 + 3123 + '@types/d3@7.4.3': 3124 + dependencies: 3125 + '@types/d3-array': 3.2.2 3126 + '@types/d3-axis': 3.0.6 3127 + '@types/d3-brush': 3.0.6 3128 + '@types/d3-chord': 3.0.6 3129 + '@types/d3-color': 3.1.3 3130 + '@types/d3-contour': 3.0.6 3131 + '@types/d3-delaunay': 6.0.4 3132 + '@types/d3-dispatch': 3.0.7 3133 + '@types/d3-drag': 3.0.7 3134 + '@types/d3-dsv': 3.0.7 3135 + '@types/d3-ease': 3.0.2 3136 + '@types/d3-fetch': 3.0.7 3137 + '@types/d3-force': 3.0.10 3138 + '@types/d3-format': 3.0.4 3139 + '@types/d3-geo': 3.1.0 3140 + '@types/d3-hierarchy': 3.1.7 3141 + '@types/d3-interpolate': 3.0.4 3142 + '@types/d3-path': 3.1.1 3143 + '@types/d3-polygon': 3.0.2 3144 + '@types/d3-quadtree': 3.0.6 3145 + '@types/d3-random': 3.0.3 3146 + '@types/d3-scale': 4.0.9 3147 + '@types/d3-scale-chromatic': 3.1.0 3148 + '@types/d3-selection': 3.0.11 3149 + '@types/d3-shape': 3.1.8 3150 + '@types/d3-time': 3.0.4 3151 + '@types/d3-time-format': 4.0.3 3152 + '@types/d3-timer': 3.0.2 3153 + '@types/d3-transition': 3.0.9 3154 + '@types/d3-zoom': 3.0.8 3155 + 3156 + '@types/debug@4.1.12': 3157 + dependencies: 3158 + '@types/ms': 2.1.0 3159 + 3160 + '@types/estree-jsx@1.0.5': 3161 + dependencies: 3162 + '@types/estree': 1.0.8 3163 + 3164 + '@types/estree@1.0.8': {} 3165 + 3166 + '@types/geojson@7946.0.16': {} 3167 + 3168 + '@types/hast@3.0.4': 3169 + dependencies: 3170 + '@types/unist': 3.0.3 3171 + 3172 + '@types/js-yaml@4.0.9': {} 3173 + 3174 + '@types/mdast@4.0.4': 3175 + dependencies: 3176 + '@types/unist': 3.0.3 3177 + 3178 + '@types/mdx@2.0.13': {} 3179 + 3180 + '@types/ms@2.1.0': {} 3181 + 3182 + '@types/nlcst@2.0.3': 3183 + dependencies: 3184 + '@types/unist': 3.0.3 3185 + 3186 + '@types/node@17.0.45': {} 3187 + 3188 + '@types/sax@1.2.7': 3189 + dependencies: 3190 + '@types/node': 17.0.45 3191 + 3192 + '@types/trusted-types@2.0.7': 3193 + optional: true 3194 + 3195 + '@types/unist@2.0.11': {} 3196 + 3197 + '@types/unist@3.0.3': {} 3198 + 3199 + '@ungap/structured-clone@1.3.0': {} 3200 + 3201 + acorn-jsx@5.3.2(acorn@8.16.0): 3202 + dependencies: 3203 + acorn: 8.16.0 3204 + 3205 + acorn@8.16.0: {} 3206 + 3207 + ansi-align@3.0.1: 3208 + dependencies: 3209 + string-width: 4.2.3 3210 + 3211 + ansi-regex@5.0.1: {} 3212 + 3213 + ansi-regex@6.2.2: {} 3214 + 3215 + ansi-styles@6.2.3: {} 3216 + 3217 + anymatch@3.1.3: 3218 + dependencies: 3219 + normalize-path: 3.0.0 3220 + picomatch: 2.3.1 3221 + 3222 + arg@5.0.2: {} 3223 + 3224 + argparse@2.0.1: {} 3225 + 3226 + aria-query@5.3.2: {} 3227 + 3228 + array-iterate@2.0.1: {} 3229 + 3230 + astring@1.9.0: {} 3231 + 3232 + astro-expressive-code@0.41.6(astro@5.17.3(rollup@4.57.1)(typescript@5.9.3)): 3233 + dependencies: 3234 + astro: 5.17.3(rollup@4.57.1)(typescript@5.9.3) 3235 + rehype-expressive-code: 0.41.6 3236 + 3237 + astro-mermaid@1.3.1(astro@5.17.3(rollup@4.57.1)(typescript@5.9.3))(mermaid@11.12.3): 3238 + dependencies: 3239 + astro: 5.17.3(rollup@4.57.1)(typescript@5.9.3) 3240 + import-meta-resolve: 4.2.0 3241 + mdast-util-to-string: 4.0.0 3242 + mermaid: 11.12.3 3243 + unist-util-visit: 5.1.0 3244 + 3245 + astro@5.17.3(rollup@4.57.1)(typescript@5.9.3): 3246 + dependencies: 3247 + '@astrojs/compiler': 2.13.1 3248 + '@astrojs/internal-helpers': 0.7.5 3249 + '@astrojs/markdown-remark': 6.3.10 3250 + '@astrojs/telemetry': 3.3.0 3251 + '@capsizecss/unpack': 4.0.0 3252 + '@oslojs/encoding': 1.1.0 3253 + '@rollup/pluginutils': 5.3.0(rollup@4.57.1) 3254 + acorn: 8.16.0 3255 + aria-query: 5.3.2 3256 + axobject-query: 4.1.0 3257 + boxen: 8.0.1 3258 + ci-info: 4.4.0 3259 + clsx: 2.1.1 3260 + common-ancestor-path: 1.0.1 3261 + cookie: 1.1.1 3262 + cssesc: 3.0.0 3263 + debug: 4.4.3 3264 + deterministic-object-hash: 2.0.2 3265 + devalue: 5.6.3 3266 + diff: 8.0.3 3267 + dlv: 1.1.3 3268 + dset: 3.1.4 3269 + es-module-lexer: 1.7.0 3270 + esbuild: 0.27.3 3271 + estree-walker: 3.0.3 3272 + flattie: 1.1.1 3273 + fontace: 0.4.1 3274 + github-slugger: 2.0.0 3275 + html-escaper: 3.0.3 3276 + http-cache-semantics: 4.2.0 3277 + import-meta-resolve: 4.2.0 3278 + js-yaml: 4.1.1 3279 + magic-string: 0.30.21 3280 + magicast: 0.5.2 3281 + mrmime: 2.0.1 3282 + neotraverse: 0.6.18 3283 + p-limit: 6.2.0 3284 + p-queue: 8.1.1 3285 + package-manager-detector: 1.6.0 3286 + piccolore: 0.1.3 3287 + picomatch: 4.0.3 3288 + prompts: 2.4.2 3289 + rehype: 13.0.2 3290 + semver: 7.7.4 3291 + shiki: 3.22.0 3292 + smol-toml: 1.6.0 3293 + svgo: 4.0.0 3294 + tinyexec: 1.0.2 3295 + tinyglobby: 0.2.15 3296 + tsconfck: 3.1.6(typescript@5.9.3) 3297 + ultrahtml: 1.6.0 3298 + unifont: 0.7.4 3299 + unist-util-visit: 5.1.0 3300 + unstorage: 1.17.4 3301 + vfile: 6.0.3 3302 + vite: 6.4.1 3303 + vitefu: 1.1.1(vite@6.4.1) 3304 + xxhash-wasm: 1.1.0 3305 + yargs-parser: 21.1.1 3306 + yocto-spinner: 0.2.3 3307 + zod: 3.25.76 3308 + zod-to-json-schema: 3.25.1(zod@3.25.76) 3309 + zod-to-ts: 1.2.0(typescript@5.9.3)(zod@3.25.76) 3310 + optionalDependencies: 3311 + sharp: 0.34.5 3312 + transitivePeerDependencies: 3313 + - '@azure/app-configuration' 3314 + - '@azure/cosmos' 3315 + - '@azure/data-tables' 3316 + - '@azure/identity' 3317 + - '@azure/keyvault-secrets' 3318 + - '@azure/storage-blob' 3319 + - '@capacitor/preferences' 3320 + - '@deno/kv' 3321 + - '@netlify/blobs' 3322 + - '@planetscale/database' 3323 + - '@types/node' 3324 + - '@upstash/redis' 3325 + - '@vercel/blob' 3326 + - '@vercel/functions' 3327 + - '@vercel/kv' 3328 + - aws4fetch 3329 + - db0 3330 + - idb-keyval 3331 + - ioredis 3332 + - jiti 3333 + - less 3334 + - lightningcss 3335 + - rollup 3336 + - sass 3337 + - sass-embedded 3338 + - stylus 3339 + - sugarss 3340 + - supports-color 3341 + - terser 3342 + - tsx 3343 + - typescript 3344 + - uploadthing 3345 + - yaml 3346 + 3347 + axobject-query@4.1.0: {} 3348 + 3349 + bail@2.0.2: {} 3350 + 3351 + base-64@1.0.0: {} 3352 + 3353 + bcp-47-match@2.0.3: {} 3354 + 3355 + bcp-47@2.1.0: 3356 + dependencies: 3357 + is-alphabetical: 2.0.1 3358 + is-alphanumerical: 2.0.1 3359 + is-decimal: 2.0.1 3360 + 3361 + boolbase@1.0.0: {} 3362 + 3363 + boxen@8.0.1: 3364 + dependencies: 3365 + ansi-align: 3.0.1 3366 + camelcase: 8.0.0 3367 + chalk: 5.6.2 3368 + cli-boxes: 3.0.0 3369 + string-width: 7.2.0 3370 + type-fest: 4.41.0 3371 + widest-line: 5.0.0 3372 + wrap-ansi: 9.0.2 3373 + 3374 + camelcase@8.0.0: {} 3375 + 3376 + ccount@2.0.1: {} 3377 + 3378 + chalk@5.6.2: {} 3379 + 3380 + character-entities-html4@2.1.0: {} 3381 + 3382 + character-entities-legacy@3.0.0: {} 3383 + 3384 + character-entities@2.0.2: {} 3385 + 3386 + character-reference-invalid@2.0.1: {} 3387 + 3388 + chevrotain-allstar@0.3.1(chevrotain@11.1.1): 3389 + dependencies: 3390 + chevrotain: 11.1.1 3391 + lodash-es: 4.17.23 3392 + 3393 + chevrotain@11.1.1: 3394 + dependencies: 3395 + '@chevrotain/cst-dts-gen': 11.1.1 3396 + '@chevrotain/gast': 11.1.1 3397 + '@chevrotain/regexp-to-ast': 11.1.1 3398 + '@chevrotain/types': 11.1.1 3399 + '@chevrotain/utils': 11.1.1 3400 + lodash-es: 4.17.23 3401 + 3402 + chokidar@5.0.0: 3403 + dependencies: 3404 + readdirp: 5.0.0 3405 + 3406 + ci-info@4.4.0: {} 3407 + 3408 + cli-boxes@3.0.0: {} 3409 + 3410 + clsx@2.1.1: {} 3411 + 3412 + collapse-white-space@2.1.0: {} 3413 + 3414 + comma-separated-tokens@2.0.3: {} 3415 + 3416 + commander@11.1.0: {} 3417 + 3418 + commander@7.2.0: {} 3419 + 3420 + commander@8.3.0: {} 3421 + 3422 + common-ancestor-path@1.0.1: {} 3423 + 3424 + confbox@0.1.8: {} 3425 + 3426 + cookie-es@1.2.2: {} 3427 + 3428 + cookie@1.1.1: {} 3429 + 3430 + cose-base@1.0.3: 3431 + dependencies: 3432 + layout-base: 1.0.2 3433 + 3434 + cose-base@2.2.0: 3435 + dependencies: 3436 + layout-base: 2.0.1 3437 + 3438 + crossws@0.3.5: 3439 + dependencies: 3440 + uncrypto: 0.1.3 3441 + 3442 + css-select@5.2.2: 3443 + dependencies: 3444 + boolbase: 1.0.0 3445 + css-what: 6.2.2 3446 + domhandler: 5.0.3 3447 + domutils: 3.2.2 3448 + nth-check: 2.1.1 3449 + 3450 + css-selector-parser@3.3.0: {} 3451 + 3452 + css-tree@2.2.1: 3453 + dependencies: 3454 + mdn-data: 2.0.28 3455 + source-map-js: 1.2.1 3456 + 3457 + css-tree@3.1.0: 3458 + dependencies: 3459 + mdn-data: 2.12.2 3460 + source-map-js: 1.2.1 3461 + 3462 + css-what@6.2.2: {} 3463 + 3464 + cssesc@3.0.0: {} 3465 + 3466 + csso@5.0.5: 3467 + dependencies: 3468 + css-tree: 2.2.1 3469 + 3470 + cytoscape-cose-bilkent@4.1.0(cytoscape@3.33.1): 3471 + dependencies: 3472 + cose-base: 1.0.3 3473 + cytoscape: 3.33.1 3474 + 3475 + cytoscape-fcose@2.2.0(cytoscape@3.33.1): 3476 + dependencies: 3477 + cose-base: 2.2.0 3478 + cytoscape: 3.33.1 3479 + 3480 + cytoscape@3.33.1: {} 3481 + 3482 + d3-array@2.12.1: 3483 + dependencies: 3484 + internmap: 1.0.1 3485 + 3486 + d3-array@3.2.4: 3487 + dependencies: 3488 + internmap: 2.0.3 3489 + 3490 + d3-axis@3.0.0: {} 3491 + 3492 + d3-brush@3.0.0: 3493 + dependencies: 3494 + d3-dispatch: 3.0.1 3495 + d3-drag: 3.0.0 3496 + d3-interpolate: 3.0.1 3497 + d3-selection: 3.0.0 3498 + d3-transition: 3.0.1(d3-selection@3.0.0) 3499 + 3500 + d3-chord@3.0.1: 3501 + dependencies: 3502 + d3-path: 3.1.0 3503 + 3504 + d3-color@3.1.0: {} 3505 + 3506 + d3-contour@4.0.2: 3507 + dependencies: 3508 + d3-array: 3.2.4 3509 + 3510 + d3-delaunay@6.0.4: 3511 + dependencies: 3512 + delaunator: 5.0.1 3513 + 3514 + d3-dispatch@3.0.1: {} 3515 + 3516 + d3-drag@3.0.0: 3517 + dependencies: 3518 + d3-dispatch: 3.0.1 3519 + d3-selection: 3.0.0 3520 + 3521 + d3-dsv@3.0.1: 3522 + dependencies: 3523 + commander: 7.2.0 3524 + iconv-lite: 0.6.3 3525 + rw: 1.3.3 3526 + 3527 + d3-ease@3.0.1: {} 3528 + 3529 + d3-fetch@3.0.1: 3530 + dependencies: 3531 + d3-dsv: 3.0.1 3532 + 3533 + d3-force@3.0.0: 3534 + dependencies: 3535 + d3-dispatch: 3.0.1 3536 + d3-quadtree: 3.0.1 3537 + d3-timer: 3.0.1 3538 + 3539 + d3-format@3.1.2: {} 3540 + 3541 + d3-geo@3.1.1: 3542 + dependencies: 3543 + d3-array: 3.2.4 3544 + 3545 + d3-hierarchy@3.1.2: {} 3546 + 3547 + d3-interpolate@3.0.1: 3548 + dependencies: 3549 + d3-color: 3.1.0 3550 + 3551 + d3-path@1.0.9: {} 3552 + 3553 + d3-path@3.1.0: {} 3554 + 3555 + d3-polygon@3.0.1: {} 3556 + 3557 + d3-quadtree@3.0.1: {} 3558 + 3559 + d3-random@3.0.1: {} 3560 + 3561 + d3-sankey@0.12.3: 3562 + dependencies: 3563 + d3-array: 2.12.1 3564 + d3-shape: 1.3.7 3565 + 3566 + d3-scale-chromatic@3.1.0: 3567 + dependencies: 3568 + d3-color: 3.1.0 3569 + d3-interpolate: 3.0.1 3570 + 3571 + d3-scale@4.0.2: 3572 + dependencies: 3573 + d3-array: 3.2.4 3574 + d3-format: 3.1.2 3575 + d3-interpolate: 3.0.1 3576 + d3-time: 3.1.0 3577 + d3-time-format: 4.1.0 3578 + 3579 + d3-selection@3.0.0: {} 3580 + 3581 + d3-shape@1.3.7: 3582 + dependencies: 3583 + d3-path: 1.0.9 3584 + 3585 + d3-shape@3.2.0: 3586 + dependencies: 3587 + d3-path: 3.1.0 3588 + 3589 + d3-time-format@4.1.0: 3590 + dependencies: 3591 + d3-time: 3.1.0 3592 + 3593 + d3-time@3.1.0: 3594 + dependencies: 3595 + d3-array: 3.2.4 3596 + 3597 + d3-timer@3.0.1: {} 3598 + 3599 + d3-transition@3.0.1(d3-selection@3.0.0): 3600 + dependencies: 3601 + d3-color: 3.1.0 3602 + d3-dispatch: 3.0.1 3603 + d3-ease: 3.0.1 3604 + d3-interpolate: 3.0.1 3605 + d3-selection: 3.0.0 3606 + d3-timer: 3.0.1 3607 + 3608 + d3-zoom@3.0.0: 3609 + dependencies: 3610 + d3-dispatch: 3.0.1 3611 + d3-drag: 3.0.0 3612 + d3-interpolate: 3.0.1 3613 + d3-selection: 3.0.0 3614 + d3-transition: 3.0.1(d3-selection@3.0.0) 3615 + 3616 + d3@7.9.0: 3617 + dependencies: 3618 + d3-array: 3.2.4 3619 + d3-axis: 3.0.0 3620 + d3-brush: 3.0.0 3621 + d3-chord: 3.0.1 3622 + d3-color: 3.1.0 3623 + d3-contour: 4.0.2 3624 + d3-delaunay: 6.0.4 3625 + d3-dispatch: 3.0.1 3626 + d3-drag: 3.0.0 3627 + d3-dsv: 3.0.1 3628 + d3-ease: 3.0.1 3629 + d3-fetch: 3.0.1 3630 + d3-force: 3.0.0 3631 + d3-format: 3.1.2 3632 + d3-geo: 3.1.1 3633 + d3-hierarchy: 3.1.2 3634 + d3-interpolate: 3.0.1 3635 + d3-path: 3.1.0 3636 + d3-polygon: 3.0.1 3637 + d3-quadtree: 3.0.1 3638 + d3-random: 3.0.1 3639 + d3-scale: 4.0.2 3640 + d3-scale-chromatic: 3.1.0 3641 + d3-selection: 3.0.0 3642 + d3-shape: 3.2.0 3643 + d3-time: 3.1.0 3644 + d3-time-format: 4.1.0 3645 + d3-timer: 3.0.1 3646 + d3-transition: 3.0.1(d3-selection@3.0.0) 3647 + d3-zoom: 3.0.0 3648 + 3649 + dagre-d3-es@7.0.13: 3650 + dependencies: 3651 + d3: 7.9.0 3652 + lodash-es: 4.17.23 3653 + 3654 + dayjs@1.11.19: {} 3655 + 3656 + debug@4.4.3: 3657 + dependencies: 3658 + ms: 2.1.3 3659 + 3660 + decode-named-character-reference@1.3.0: 3661 + dependencies: 3662 + character-entities: 2.0.2 3663 + 3664 + defu@6.1.4: {} 3665 + 3666 + delaunator@5.0.1: 3667 + dependencies: 3668 + robust-predicates: 3.0.2 3669 + 3670 + dequal@2.0.3: {} 3671 + 3672 + destr@2.0.5: {} 3673 + 3674 + detect-libc@2.1.2: {} 3675 + 3676 + deterministic-object-hash@2.0.2: 3677 + dependencies: 3678 + base-64: 1.0.0 3679 + 3680 + devalue@5.6.3: {} 3681 + 3682 + devlop@1.1.0: 3683 + dependencies: 3684 + dequal: 2.0.3 3685 + 3686 + diff@8.0.3: {} 3687 + 3688 + direction@2.0.1: {} 3689 + 3690 + dlv@1.1.3: {} 3691 + 3692 + dom-serializer@2.0.0: 3693 + dependencies: 3694 + domelementtype: 2.3.0 3695 + domhandler: 5.0.3 3696 + entities: 4.5.0 3697 + 3698 + domelementtype@2.3.0: {} 3699 + 3700 + domhandler@5.0.3: 3701 + dependencies: 3702 + domelementtype: 2.3.0 3703 + 3704 + dompurify@3.3.1: 3705 + optionalDependencies: 3706 + '@types/trusted-types': 2.0.7 3707 + 3708 + domutils@3.2.2: 3709 + dependencies: 3710 + dom-serializer: 2.0.0 3711 + domelementtype: 2.3.0 3712 + domhandler: 5.0.3 3713 + 3714 + dset@3.1.4: {} 3715 + 3716 + emoji-regex@10.6.0: {} 3717 + 3718 + emoji-regex@8.0.0: {} 3719 + 3720 + entities@4.5.0: {} 3721 + 3722 + entities@6.0.1: {} 3723 + 3724 + es-module-lexer@1.7.0: {} 3725 + 3726 + esast-util-from-estree@2.0.0: 3727 + dependencies: 3728 + '@types/estree-jsx': 1.0.5 3729 + devlop: 1.1.0 3730 + estree-util-visit: 2.0.0 3731 + unist-util-position-from-estree: 2.0.0 3732 + 3733 + esast-util-from-js@2.0.1: 3734 + dependencies: 3735 + '@types/estree-jsx': 1.0.5 3736 + acorn: 8.16.0 3737 + esast-util-from-estree: 2.0.0 3738 + vfile-message: 4.0.3 3739 + 3740 + esbuild@0.25.12: 3741 + optionalDependencies: 3742 + '@esbuild/aix-ppc64': 0.25.12 3743 + '@esbuild/android-arm': 0.25.12 3744 + '@esbuild/android-arm64': 0.25.12 3745 + '@esbuild/android-x64': 0.25.12 3746 + '@esbuild/darwin-arm64': 0.25.12 3747 + '@esbuild/darwin-x64': 0.25.12 3748 + '@esbuild/freebsd-arm64': 0.25.12 3749 + '@esbuild/freebsd-x64': 0.25.12 3750 + '@esbuild/linux-arm': 0.25.12 3751 + '@esbuild/linux-arm64': 0.25.12 3752 + '@esbuild/linux-ia32': 0.25.12 3753 + '@esbuild/linux-loong64': 0.25.12 3754 + '@esbuild/linux-mips64el': 0.25.12 3755 + '@esbuild/linux-ppc64': 0.25.12 3756 + '@esbuild/linux-riscv64': 0.25.12 3757 + '@esbuild/linux-s390x': 0.25.12 3758 + '@esbuild/linux-x64': 0.25.12 3759 + '@esbuild/netbsd-arm64': 0.25.12 3760 + '@esbuild/netbsd-x64': 0.25.12 3761 + '@esbuild/openbsd-arm64': 0.25.12 3762 + '@esbuild/openbsd-x64': 0.25.12 3763 + '@esbuild/openharmony-arm64': 0.25.12 3764 + '@esbuild/sunos-x64': 0.25.12 3765 + '@esbuild/win32-arm64': 0.25.12 3766 + '@esbuild/win32-ia32': 0.25.12 3767 + '@esbuild/win32-x64': 0.25.12 3768 + 3769 + esbuild@0.27.3: 3770 + optionalDependencies: 3771 + '@esbuild/aix-ppc64': 0.27.3 3772 + '@esbuild/android-arm': 0.27.3 3773 + '@esbuild/android-arm64': 0.27.3 3774 + '@esbuild/android-x64': 0.27.3 3775 + '@esbuild/darwin-arm64': 0.27.3 3776 + '@esbuild/darwin-x64': 0.27.3 3777 + '@esbuild/freebsd-arm64': 0.27.3 3778 + '@esbuild/freebsd-x64': 0.27.3 3779 + '@esbuild/linux-arm': 0.27.3 3780 + '@esbuild/linux-arm64': 0.27.3 3781 + '@esbuild/linux-ia32': 0.27.3 3782 + '@esbuild/linux-loong64': 0.27.3 3783 + '@esbuild/linux-mips64el': 0.27.3 3784 + '@esbuild/linux-ppc64': 0.27.3 3785 + '@esbuild/linux-riscv64': 0.27.3 3786 + '@esbuild/linux-s390x': 0.27.3 3787 + '@esbuild/linux-x64': 0.27.3 3788 + '@esbuild/netbsd-arm64': 0.27.3 3789 + '@esbuild/netbsd-x64': 0.27.3 3790 + '@esbuild/openbsd-arm64': 0.27.3 3791 + '@esbuild/openbsd-x64': 0.27.3 3792 + '@esbuild/openharmony-arm64': 0.27.3 3793 + '@esbuild/sunos-x64': 0.27.3 3794 + '@esbuild/win32-arm64': 0.27.3 3795 + '@esbuild/win32-ia32': 0.27.3 3796 + '@esbuild/win32-x64': 0.27.3 3797 + 3798 + escape-string-regexp@5.0.0: {} 3799 + 3800 + estree-util-attach-comments@3.0.0: 3801 + dependencies: 3802 + '@types/estree': 1.0.8 3803 + 3804 + estree-util-build-jsx@3.0.1: 3805 + dependencies: 3806 + '@types/estree-jsx': 1.0.5 3807 + devlop: 1.1.0 3808 + estree-util-is-identifier-name: 3.0.0 3809 + estree-walker: 3.0.3 3810 + 3811 + estree-util-is-identifier-name@3.0.0: {} 3812 + 3813 + estree-util-scope@1.0.0: 3814 + dependencies: 3815 + '@types/estree': 1.0.8 3816 + devlop: 1.1.0 3817 + 3818 + estree-util-to-js@2.0.0: 3819 + dependencies: 3820 + '@types/estree-jsx': 1.0.5 3821 + astring: 1.9.0 3822 + source-map: 0.7.6 3823 + 3824 + estree-util-visit@2.0.0: 3825 + dependencies: 3826 + '@types/estree-jsx': 1.0.5 3827 + '@types/unist': 3.0.3 3828 + 3829 + estree-walker@2.0.2: {} 3830 + 3831 + estree-walker@3.0.3: 3832 + dependencies: 3833 + '@types/estree': 1.0.8 3834 + 3835 + eventemitter3@5.0.4: {} 3836 + 3837 + expressive-code@0.41.6: 3838 + dependencies: 3839 + '@expressive-code/core': 0.41.6 3840 + '@expressive-code/plugin-frames': 0.41.6 3841 + '@expressive-code/plugin-shiki': 0.41.6 3842 + '@expressive-code/plugin-text-markers': 0.41.6 3843 + 3844 + extend@3.0.2: {} 3845 + 3846 + fdir@6.5.0(picomatch@4.0.3): 3847 + optionalDependencies: 3848 + picomatch: 4.0.3 3849 + 3850 + flattie@1.1.1: {} 3851 + 3852 + fontace@0.4.1: 3853 + dependencies: 3854 + fontkitten: 1.0.2 3855 + 3856 + fontkitten@1.0.2: 3857 + dependencies: 3858 + tiny-inflate: 1.0.3 3859 + 3860 + fsevents@2.3.3: 3861 + optional: true 3862 + 3863 + get-east-asian-width@1.5.0: {} 3864 + 3865 + github-slugger@2.0.0: {} 3866 + 3867 + h3@1.15.5: 3868 + dependencies: 3869 + cookie-es: 1.2.2 3870 + crossws: 0.3.5 3871 + defu: 6.1.4 3872 + destr: 2.0.5 3873 + iron-webcrypto: 1.2.1 3874 + node-mock-http: 1.0.4 3875 + radix3: 1.1.2 3876 + ufo: 1.6.3 3877 + uncrypto: 0.1.3 3878 + 3879 + hachure-fill@0.5.2: {} 3880 + 3881 + hast-util-embedded@3.0.0: 3882 + dependencies: 3883 + '@types/hast': 3.0.4 3884 + hast-util-is-element: 3.0.0 3885 + 3886 + hast-util-format@1.1.0: 3887 + dependencies: 3888 + '@types/hast': 3.0.4 3889 + hast-util-embedded: 3.0.0 3890 + hast-util-minify-whitespace: 1.0.1 3891 + hast-util-phrasing: 3.0.1 3892 + hast-util-whitespace: 3.0.0 3893 + html-whitespace-sensitive-tag-names: 3.0.1 3894 + unist-util-visit-parents: 6.0.2 3895 + 3896 + hast-util-from-html@2.0.3: 3897 + dependencies: 3898 + '@types/hast': 3.0.4 3899 + devlop: 1.1.0 3900 + hast-util-from-parse5: 8.0.3 3901 + parse5: 7.3.0 3902 + vfile: 6.0.3 3903 + vfile-message: 4.0.3 3904 + 3905 + hast-util-from-parse5@8.0.3: 3906 + dependencies: 3907 + '@types/hast': 3.0.4 3908 + '@types/unist': 3.0.3 3909 + devlop: 1.1.0 3910 + hastscript: 9.0.1 3911 + property-information: 7.1.0 3912 + vfile: 6.0.3 3913 + vfile-location: 5.0.3 3914 + web-namespaces: 2.0.1 3915 + 3916 + hast-util-has-property@3.0.0: 3917 + dependencies: 3918 + '@types/hast': 3.0.4 3919 + 3920 + hast-util-is-body-ok-link@3.0.1: 3921 + dependencies: 3922 + '@types/hast': 3.0.4 3923 + 3924 + hast-util-is-element@3.0.0: 3925 + dependencies: 3926 + '@types/hast': 3.0.4 3927 + 3928 + hast-util-minify-whitespace@1.0.1: 3929 + dependencies: 3930 + '@types/hast': 3.0.4 3931 + hast-util-embedded: 3.0.0 3932 + hast-util-is-element: 3.0.0 3933 + hast-util-whitespace: 3.0.0 3934 + unist-util-is: 6.0.1 3935 + 3936 + hast-util-parse-selector@4.0.0: 3937 + dependencies: 3938 + '@types/hast': 3.0.4 3939 + 3940 + hast-util-phrasing@3.0.1: 3941 + dependencies: 3942 + '@types/hast': 3.0.4 3943 + hast-util-embedded: 3.0.0 3944 + hast-util-has-property: 3.0.0 3945 + hast-util-is-body-ok-link: 3.0.1 3946 + hast-util-is-element: 3.0.0 3947 + 3948 + hast-util-raw@9.1.0: 3949 + dependencies: 3950 + '@types/hast': 3.0.4 3951 + '@types/unist': 3.0.3 3952 + '@ungap/structured-clone': 1.3.0 3953 + hast-util-from-parse5: 8.0.3 3954 + hast-util-to-parse5: 8.0.1 3955 + html-void-elements: 3.0.0 3956 + mdast-util-to-hast: 13.2.1 3957 + parse5: 7.3.0 3958 + unist-util-position: 5.0.0 3959 + unist-util-visit: 5.1.0 3960 + vfile: 6.0.3 3961 + web-namespaces: 2.0.1 3962 + zwitch: 2.0.4 3963 + 3964 + hast-util-select@6.0.4: 3965 + dependencies: 3966 + '@types/hast': 3.0.4 3967 + '@types/unist': 3.0.3 3968 + bcp-47-match: 2.0.3 3969 + comma-separated-tokens: 2.0.3 3970 + css-selector-parser: 3.3.0 3971 + devlop: 1.1.0 3972 + direction: 2.0.1 3973 + hast-util-has-property: 3.0.0 3974 + hast-util-to-string: 3.0.1 3975 + hast-util-whitespace: 3.0.0 3976 + nth-check: 2.1.1 3977 + property-information: 7.1.0 3978 + space-separated-tokens: 2.0.2 3979 + unist-util-visit: 5.1.0 3980 + zwitch: 2.0.4 3981 + 3982 + hast-util-to-estree@3.1.3: 3983 + dependencies: 3984 + '@types/estree': 1.0.8 3985 + '@types/estree-jsx': 1.0.5 3986 + '@types/hast': 3.0.4 3987 + comma-separated-tokens: 2.0.3 3988 + devlop: 1.1.0 3989 + estree-util-attach-comments: 3.0.0 3990 + estree-util-is-identifier-name: 3.0.0 3991 + hast-util-whitespace: 3.0.0 3992 + mdast-util-mdx-expression: 2.0.1 3993 + mdast-util-mdx-jsx: 3.2.0 3994 + mdast-util-mdxjs-esm: 2.0.1 3995 + property-information: 7.1.0 3996 + space-separated-tokens: 2.0.2 3997 + style-to-js: 1.1.21 3998 + unist-util-position: 5.0.0 3999 + zwitch: 2.0.4 4000 + transitivePeerDependencies: 4001 + - supports-color 4002 + 4003 + hast-util-to-html@9.0.5: 4004 + dependencies: 4005 + '@types/hast': 3.0.4 4006 + '@types/unist': 3.0.3 4007 + ccount: 2.0.1 4008 + comma-separated-tokens: 2.0.3 4009 + hast-util-whitespace: 3.0.0 4010 + html-void-elements: 3.0.0 4011 + mdast-util-to-hast: 13.2.1 4012 + property-information: 7.1.0 4013 + space-separated-tokens: 2.0.2 4014 + stringify-entities: 4.0.4 4015 + zwitch: 2.0.4 4016 + 4017 + hast-util-to-jsx-runtime@2.3.6: 4018 + dependencies: 4019 + '@types/estree': 1.0.8 4020 + '@types/hast': 3.0.4 4021 + '@types/unist': 3.0.3 4022 + comma-separated-tokens: 2.0.3 4023 + devlop: 1.1.0 4024 + estree-util-is-identifier-name: 3.0.0 4025 + hast-util-whitespace: 3.0.0 4026 + mdast-util-mdx-expression: 2.0.1 4027 + mdast-util-mdx-jsx: 3.2.0 4028 + mdast-util-mdxjs-esm: 2.0.1 4029 + property-information: 7.1.0 4030 + space-separated-tokens: 2.0.2 4031 + style-to-js: 1.1.21 4032 + unist-util-position: 5.0.0 4033 + vfile-message: 4.0.3 4034 + transitivePeerDependencies: 4035 + - supports-color 4036 + 4037 + hast-util-to-parse5@8.0.1: 4038 + dependencies: 4039 + '@types/hast': 3.0.4 4040 + comma-separated-tokens: 2.0.3 4041 + devlop: 1.1.0 4042 + property-information: 7.1.0 4043 + space-separated-tokens: 2.0.2 4044 + web-namespaces: 2.0.1 4045 + zwitch: 2.0.4 4046 + 4047 + hast-util-to-string@3.0.1: 4048 + dependencies: 4049 + '@types/hast': 3.0.4 4050 + 4051 + hast-util-to-text@4.0.2: 4052 + dependencies: 4053 + '@types/hast': 3.0.4 4054 + '@types/unist': 3.0.3 4055 + hast-util-is-element: 3.0.0 4056 + unist-util-find-after: 5.0.0 4057 + 4058 + hast-util-whitespace@3.0.0: 4059 + dependencies: 4060 + '@types/hast': 3.0.4 4061 + 4062 + hastscript@9.0.1: 4063 + dependencies: 4064 + '@types/hast': 3.0.4 4065 + comma-separated-tokens: 2.0.3 4066 + hast-util-parse-selector: 4.0.0 4067 + property-information: 7.1.0 4068 + space-separated-tokens: 2.0.2 4069 + 4070 + html-escaper@3.0.3: {} 4071 + 4072 + html-void-elements@3.0.0: {} 4073 + 4074 + html-whitespace-sensitive-tag-names@3.0.1: {} 4075 + 4076 + http-cache-semantics@4.2.0: {} 4077 + 4078 + i18next@23.16.8: 4079 + dependencies: 4080 + '@babel/runtime': 7.28.6 4081 + 4082 + iconv-lite@0.6.3: 4083 + dependencies: 4084 + safer-buffer: 2.1.2 4085 + 4086 + import-meta-resolve@4.2.0: {} 4087 + 4088 + inline-style-parser@0.2.7: {} 4089 + 4090 + internmap@1.0.1: {} 4091 + 4092 + internmap@2.0.3: {} 4093 + 4094 + iron-webcrypto@1.2.1: {} 4095 + 4096 + is-alphabetical@2.0.1: {} 4097 + 4098 + is-alphanumerical@2.0.1: 4099 + dependencies: 4100 + is-alphabetical: 2.0.1 4101 + is-decimal: 2.0.1 4102 + 4103 + is-decimal@2.0.1: {} 4104 + 4105 + is-docker@3.0.0: {} 4106 + 4107 + is-fullwidth-code-point@3.0.0: {} 4108 + 4109 + is-hexadecimal@2.0.1: {} 4110 + 4111 + is-inside-container@1.0.0: 4112 + dependencies: 4113 + is-docker: 3.0.0 4114 + 4115 + is-plain-obj@4.1.0: {} 4116 + 4117 + is-wsl@3.1.1: 4118 + dependencies: 4119 + is-inside-container: 1.0.0 4120 + 4121 + js-yaml@4.1.1: 4122 + dependencies: 4123 + argparse: 2.0.1 4124 + 4125 + katex@0.16.28: 4126 + dependencies: 4127 + commander: 8.3.0 4128 + 4129 + khroma@2.1.0: {} 4130 + 4131 + kleur@3.0.3: {} 4132 + 4133 + klona@2.0.6: {} 4134 + 4135 + langium@4.2.1: 4136 + dependencies: 4137 + chevrotain: 11.1.1 4138 + chevrotain-allstar: 0.3.1(chevrotain@11.1.1) 4139 + vscode-languageserver: 9.0.1 4140 + vscode-languageserver-textdocument: 1.0.12 4141 + vscode-uri: 3.1.0 4142 + 4143 + layout-base@1.0.2: {} 4144 + 4145 + layout-base@2.0.1: {} 4146 + 4147 + lodash-es@4.17.23: {} 4148 + 4149 + longest-streak@3.1.0: {} 4150 + 4151 + lru-cache@11.2.6: {} 4152 + 4153 + magic-string@0.30.21: 4154 + dependencies: 4155 + '@jridgewell/sourcemap-codec': 1.5.5 4156 + 4157 + magicast@0.5.2: 4158 + dependencies: 4159 + '@babel/parser': 7.29.0 4160 + '@babel/types': 7.29.0 4161 + source-map-js: 1.2.1 4162 + 4163 + markdown-extensions@2.0.0: {} 4164 + 4165 + markdown-table@3.0.4: {} 4166 + 4167 + marked@16.4.2: {} 4168 + 4169 + mdast-util-definitions@6.0.0: 4170 + dependencies: 4171 + '@types/mdast': 4.0.4 4172 + '@types/unist': 3.0.3 4173 + unist-util-visit: 5.1.0 4174 + 4175 + mdast-util-directive@3.1.0: 4176 + dependencies: 4177 + '@types/mdast': 4.0.4 4178 + '@types/unist': 3.0.3 4179 + ccount: 2.0.1 4180 + devlop: 1.1.0 4181 + mdast-util-from-markdown: 2.0.2 4182 + mdast-util-to-markdown: 2.1.2 4183 + parse-entities: 4.0.2 4184 + stringify-entities: 4.0.4 4185 + unist-util-visit-parents: 6.0.2 4186 + transitivePeerDependencies: 4187 + - supports-color 4188 + 4189 + mdast-util-find-and-replace@3.0.2: 4190 + dependencies: 4191 + '@types/mdast': 4.0.4 4192 + escape-string-regexp: 5.0.0 4193 + unist-util-is: 6.0.1 4194 + unist-util-visit-parents: 6.0.2 4195 + 4196 + mdast-util-from-markdown@2.0.2: 4197 + dependencies: 4198 + '@types/mdast': 4.0.4 4199 + '@types/unist': 3.0.3 4200 + decode-named-character-reference: 1.3.0 4201 + devlop: 1.1.0 4202 + mdast-util-to-string: 4.0.0 4203 + micromark: 4.0.2 4204 + micromark-util-decode-numeric-character-reference: 2.0.2 4205 + micromark-util-decode-string: 2.0.1 4206 + micromark-util-normalize-identifier: 2.0.1 4207 + micromark-util-symbol: 2.0.1 4208 + micromark-util-types: 2.0.2 4209 + unist-util-stringify-position: 4.0.0 4210 + transitivePeerDependencies: 4211 + - supports-color 4212 + 4213 + mdast-util-gfm-autolink-literal@2.0.1: 4214 + dependencies: 4215 + '@types/mdast': 4.0.4 4216 + ccount: 2.0.1 4217 + devlop: 1.1.0 4218 + mdast-util-find-and-replace: 3.0.2 4219 + micromark-util-character: 2.1.1 4220 + 4221 + mdast-util-gfm-footnote@2.1.0: 4222 + dependencies: 4223 + '@types/mdast': 4.0.4 4224 + devlop: 1.1.0 4225 + mdast-util-from-markdown: 2.0.2 4226 + mdast-util-to-markdown: 2.1.2 4227 + micromark-util-normalize-identifier: 2.0.1 4228 + transitivePeerDependencies: 4229 + - supports-color 4230 + 4231 + mdast-util-gfm-strikethrough@2.0.0: 4232 + dependencies: 4233 + '@types/mdast': 4.0.4 4234 + mdast-util-from-markdown: 2.0.2 4235 + mdast-util-to-markdown: 2.1.2 4236 + transitivePeerDependencies: 4237 + - supports-color 4238 + 4239 + mdast-util-gfm-table@2.0.0: 4240 + dependencies: 4241 + '@types/mdast': 4.0.4 4242 + devlop: 1.1.0 4243 + markdown-table: 3.0.4 4244 + mdast-util-from-markdown: 2.0.2 4245 + mdast-util-to-markdown: 2.1.2 4246 + transitivePeerDependencies: 4247 + - supports-color 4248 + 4249 + mdast-util-gfm-task-list-item@2.0.0: 4250 + dependencies: 4251 + '@types/mdast': 4.0.4 4252 + devlop: 1.1.0 4253 + mdast-util-from-markdown: 2.0.2 4254 + mdast-util-to-markdown: 2.1.2 4255 + transitivePeerDependencies: 4256 + - supports-color 4257 + 4258 + mdast-util-gfm@3.1.0: 4259 + dependencies: 4260 + mdast-util-from-markdown: 2.0.2 4261 + mdast-util-gfm-autolink-literal: 2.0.1 4262 + mdast-util-gfm-footnote: 2.1.0 4263 + mdast-util-gfm-strikethrough: 2.0.0 4264 + mdast-util-gfm-table: 2.0.0 4265 + mdast-util-gfm-task-list-item: 2.0.0 4266 + mdast-util-to-markdown: 2.1.2 4267 + transitivePeerDependencies: 4268 + - supports-color 4269 + 4270 + mdast-util-mdx-expression@2.0.1: 4271 + dependencies: 4272 + '@types/estree-jsx': 1.0.5 4273 + '@types/hast': 3.0.4 4274 + '@types/mdast': 4.0.4 4275 + devlop: 1.1.0 4276 + mdast-util-from-markdown: 2.0.2 4277 + mdast-util-to-markdown: 2.1.2 4278 + transitivePeerDependencies: 4279 + - supports-color 4280 + 4281 + mdast-util-mdx-jsx@3.2.0: 4282 + dependencies: 4283 + '@types/estree-jsx': 1.0.5 4284 + '@types/hast': 3.0.4 4285 + '@types/mdast': 4.0.4 4286 + '@types/unist': 3.0.3 4287 + ccount: 2.0.1 4288 + devlop: 1.1.0 4289 + mdast-util-from-markdown: 2.0.2 4290 + mdast-util-to-markdown: 2.1.2 4291 + parse-entities: 4.0.2 4292 + stringify-entities: 4.0.4 4293 + unist-util-stringify-position: 4.0.0 4294 + vfile-message: 4.0.3 4295 + transitivePeerDependencies: 4296 + - supports-color 4297 + 4298 + mdast-util-mdx@3.0.0: 4299 + dependencies: 4300 + mdast-util-from-markdown: 2.0.2 4301 + mdast-util-mdx-expression: 2.0.1 4302 + mdast-util-mdx-jsx: 3.2.0 4303 + mdast-util-mdxjs-esm: 2.0.1 4304 + mdast-util-to-markdown: 2.1.2 4305 + transitivePeerDependencies: 4306 + - supports-color 4307 + 4308 + mdast-util-mdxjs-esm@2.0.1: 4309 + dependencies: 4310 + '@types/estree-jsx': 1.0.5 4311 + '@types/hast': 3.0.4 4312 + '@types/mdast': 4.0.4 4313 + devlop: 1.1.0 4314 + mdast-util-from-markdown: 2.0.2 4315 + mdast-util-to-markdown: 2.1.2 4316 + transitivePeerDependencies: 4317 + - supports-color 4318 + 4319 + mdast-util-phrasing@4.1.0: 4320 + dependencies: 4321 + '@types/mdast': 4.0.4 4322 + unist-util-is: 6.0.1 4323 + 4324 + mdast-util-to-hast@13.2.1: 4325 + dependencies: 4326 + '@types/hast': 3.0.4 4327 + '@types/mdast': 4.0.4 4328 + '@ungap/structured-clone': 1.3.0 4329 + devlop: 1.1.0 4330 + micromark-util-sanitize-uri: 2.0.1 4331 + trim-lines: 3.0.1 4332 + unist-util-position: 5.0.0 4333 + unist-util-visit: 5.1.0 4334 + vfile: 6.0.3 4335 + 4336 + mdast-util-to-markdown@2.1.2: 4337 + dependencies: 4338 + '@types/mdast': 4.0.4 4339 + '@types/unist': 3.0.3 4340 + longest-streak: 3.1.0 4341 + mdast-util-phrasing: 4.1.0 4342 + mdast-util-to-string: 4.0.0 4343 + micromark-util-classify-character: 2.0.1 4344 + micromark-util-decode-string: 2.0.1 4345 + unist-util-visit: 5.1.0 4346 + zwitch: 2.0.4 4347 + 4348 + mdast-util-to-string@4.0.0: 4349 + dependencies: 4350 + '@types/mdast': 4.0.4 4351 + 4352 + mdn-data@2.0.28: {} 4353 + 4354 + mdn-data@2.12.2: {} 4355 + 4356 + mermaid@11.12.3: 4357 + dependencies: 4358 + '@braintree/sanitize-url': 7.1.2 4359 + '@iconify/utils': 3.1.0 4360 + '@mermaid-js/parser': 1.0.0 4361 + '@types/d3': 7.4.3 4362 + cytoscape: 3.33.1 4363 + cytoscape-cose-bilkent: 4.1.0(cytoscape@3.33.1) 4364 + cytoscape-fcose: 2.2.0(cytoscape@3.33.1) 4365 + d3: 7.9.0 4366 + d3-sankey: 0.12.3 4367 + dagre-d3-es: 7.0.13 4368 + dayjs: 1.11.19 4369 + dompurify: 3.3.1 4370 + katex: 0.16.28 4371 + khroma: 2.1.0 4372 + lodash-es: 4.17.23 4373 + marked: 16.4.2 4374 + roughjs: 4.6.6 4375 + stylis: 4.3.6 4376 + ts-dedent: 2.2.0 4377 + uuid: 11.1.0 4378 + 4379 + micromark-core-commonmark@2.0.3: 4380 + dependencies: 4381 + decode-named-character-reference: 1.3.0 4382 + devlop: 1.1.0 4383 + micromark-factory-destination: 2.0.1 4384 + micromark-factory-label: 2.0.1 4385 + micromark-factory-space: 2.0.1 4386 + micromark-factory-title: 2.0.1 4387 + micromark-factory-whitespace: 2.0.1 4388 + micromark-util-character: 2.1.1 4389 + micromark-util-chunked: 2.0.1 4390 + micromark-util-classify-character: 2.0.1 4391 + micromark-util-html-tag-name: 2.0.1 4392 + micromark-util-normalize-identifier: 2.0.1 4393 + micromark-util-resolve-all: 2.0.1 4394 + micromark-util-subtokenize: 2.1.0 4395 + micromark-util-symbol: 2.0.1 4396 + micromark-util-types: 2.0.2 4397 + 4398 + micromark-extension-directive@3.0.2: 4399 + dependencies: 4400 + devlop: 1.1.0 4401 + micromark-factory-space: 2.0.1 4402 + micromark-factory-whitespace: 2.0.1 4403 + micromark-util-character: 2.1.1 4404 + micromark-util-symbol: 2.0.1 4405 + micromark-util-types: 2.0.2 4406 + parse-entities: 4.0.2 4407 + 4408 + micromark-extension-gfm-autolink-literal@2.1.0: 4409 + dependencies: 4410 + micromark-util-character: 2.1.1 4411 + micromark-util-sanitize-uri: 2.0.1 4412 + micromark-util-symbol: 2.0.1 4413 + micromark-util-types: 2.0.2 4414 + 4415 + micromark-extension-gfm-footnote@2.1.0: 4416 + dependencies: 4417 + devlop: 1.1.0 4418 + micromark-core-commonmark: 2.0.3 4419 + micromark-factory-space: 2.0.1 4420 + micromark-util-character: 2.1.1 4421 + micromark-util-normalize-identifier: 2.0.1 4422 + micromark-util-sanitize-uri: 2.0.1 4423 + micromark-util-symbol: 2.0.1 4424 + micromark-util-types: 2.0.2 4425 + 4426 + micromark-extension-gfm-strikethrough@2.1.0: 4427 + dependencies: 4428 + devlop: 1.1.0 4429 + micromark-util-chunked: 2.0.1 4430 + micromark-util-classify-character: 2.0.1 4431 + micromark-util-resolve-all: 2.0.1 4432 + micromark-util-symbol: 2.0.1 4433 + micromark-util-types: 2.0.2 4434 + 4435 + micromark-extension-gfm-table@2.1.1: 4436 + dependencies: 4437 + devlop: 1.1.0 4438 + micromark-factory-space: 2.0.1 4439 + micromark-util-character: 2.1.1 4440 + micromark-util-symbol: 2.0.1 4441 + micromark-util-types: 2.0.2 4442 + 4443 + micromark-extension-gfm-tagfilter@2.0.0: 4444 + dependencies: 4445 + micromark-util-types: 2.0.2 4446 + 4447 + micromark-extension-gfm-task-list-item@2.1.0: 4448 + dependencies: 4449 + devlop: 1.1.0 4450 + micromark-factory-space: 2.0.1 4451 + micromark-util-character: 2.1.1 4452 + micromark-util-symbol: 2.0.1 4453 + micromark-util-types: 2.0.2 4454 + 4455 + micromark-extension-gfm@3.0.0: 4456 + dependencies: 4457 + micromark-extension-gfm-autolink-literal: 2.1.0 4458 + micromark-extension-gfm-footnote: 2.1.0 4459 + micromark-extension-gfm-strikethrough: 2.1.0 4460 + micromark-extension-gfm-table: 2.1.1 4461 + micromark-extension-gfm-tagfilter: 2.0.0 4462 + micromark-extension-gfm-task-list-item: 2.1.0 4463 + micromark-util-combine-extensions: 2.0.1 4464 + micromark-util-types: 2.0.2 4465 + 4466 + micromark-extension-mdx-expression@3.0.1: 4467 + dependencies: 4468 + '@types/estree': 1.0.8 4469 + devlop: 1.1.0 4470 + micromark-factory-mdx-expression: 2.0.3 4471 + micromark-factory-space: 2.0.1 4472 + micromark-util-character: 2.1.1 4473 + micromark-util-events-to-acorn: 2.0.3 4474 + micromark-util-symbol: 2.0.1 4475 + micromark-util-types: 2.0.2 4476 + 4477 + micromark-extension-mdx-jsx@3.0.2: 4478 + dependencies: 4479 + '@types/estree': 1.0.8 4480 + devlop: 1.1.0 4481 + estree-util-is-identifier-name: 3.0.0 4482 + micromark-factory-mdx-expression: 2.0.3 4483 + micromark-factory-space: 2.0.1 4484 + micromark-util-character: 2.1.1 4485 + micromark-util-events-to-acorn: 2.0.3 4486 + micromark-util-symbol: 2.0.1 4487 + micromark-util-types: 2.0.2 4488 + vfile-message: 4.0.3 4489 + 4490 + micromark-extension-mdx-md@2.0.0: 4491 + dependencies: 4492 + micromark-util-types: 2.0.2 4493 + 4494 + micromark-extension-mdxjs-esm@3.0.0: 4495 + dependencies: 4496 + '@types/estree': 1.0.8 4497 + devlop: 1.1.0 4498 + micromark-core-commonmark: 2.0.3 4499 + micromark-util-character: 2.1.1 4500 + micromark-util-events-to-acorn: 2.0.3 4501 + micromark-util-symbol: 2.0.1 4502 + micromark-util-types: 2.0.2 4503 + unist-util-position-from-estree: 2.0.0 4504 + vfile-message: 4.0.3 4505 + 4506 + micromark-extension-mdxjs@3.0.0: 4507 + dependencies: 4508 + acorn: 8.16.0 4509 + acorn-jsx: 5.3.2(acorn@8.16.0) 4510 + micromark-extension-mdx-expression: 3.0.1 4511 + micromark-extension-mdx-jsx: 3.0.2 4512 + micromark-extension-mdx-md: 2.0.0 4513 + micromark-extension-mdxjs-esm: 3.0.0 4514 + micromark-util-combine-extensions: 2.0.1 4515 + micromark-util-types: 2.0.2 4516 + 4517 + micromark-factory-destination@2.0.1: 4518 + dependencies: 4519 + micromark-util-character: 2.1.1 4520 + micromark-util-symbol: 2.0.1 4521 + micromark-util-types: 2.0.2 4522 + 4523 + micromark-factory-label@2.0.1: 4524 + dependencies: 4525 + devlop: 1.1.0 4526 + micromark-util-character: 2.1.1 4527 + micromark-util-symbol: 2.0.1 4528 + micromark-util-types: 2.0.2 4529 + 4530 + micromark-factory-mdx-expression@2.0.3: 4531 + dependencies: 4532 + '@types/estree': 1.0.8 4533 + devlop: 1.1.0 4534 + micromark-factory-space: 2.0.1 4535 + micromark-util-character: 2.1.1 4536 + micromark-util-events-to-acorn: 2.0.3 4537 + micromark-util-symbol: 2.0.1 4538 + micromark-util-types: 2.0.2 4539 + unist-util-position-from-estree: 2.0.0 4540 + vfile-message: 4.0.3 4541 + 4542 + micromark-factory-space@2.0.1: 4543 + dependencies: 4544 + micromark-util-character: 2.1.1 4545 + micromark-util-types: 2.0.2 4546 + 4547 + micromark-factory-title@2.0.1: 4548 + dependencies: 4549 + micromark-factory-space: 2.0.1 4550 + micromark-util-character: 2.1.1 4551 + micromark-util-symbol: 2.0.1 4552 + micromark-util-types: 2.0.2 4553 + 4554 + micromark-factory-whitespace@2.0.1: 4555 + dependencies: 4556 + micromark-factory-space: 2.0.1 4557 + micromark-util-character: 2.1.1 4558 + micromark-util-symbol: 2.0.1 4559 + micromark-util-types: 2.0.2 4560 + 4561 + micromark-util-character@2.1.1: 4562 + dependencies: 4563 + micromark-util-symbol: 2.0.1 4564 + micromark-util-types: 2.0.2 4565 + 4566 + micromark-util-chunked@2.0.1: 4567 + dependencies: 4568 + micromark-util-symbol: 2.0.1 4569 + 4570 + micromark-util-classify-character@2.0.1: 4571 + dependencies: 4572 + micromark-util-character: 2.1.1 4573 + micromark-util-symbol: 2.0.1 4574 + micromark-util-types: 2.0.2 4575 + 4576 + micromark-util-combine-extensions@2.0.1: 4577 + dependencies: 4578 + micromark-util-chunked: 2.0.1 4579 + micromark-util-types: 2.0.2 4580 + 4581 + micromark-util-decode-numeric-character-reference@2.0.2: 4582 + dependencies: 4583 + micromark-util-symbol: 2.0.1 4584 + 4585 + micromark-util-decode-string@2.0.1: 4586 + dependencies: 4587 + decode-named-character-reference: 1.3.0 4588 + micromark-util-character: 2.1.1 4589 + micromark-util-decode-numeric-character-reference: 2.0.2 4590 + micromark-util-symbol: 2.0.1 4591 + 4592 + micromark-util-encode@2.0.1: {} 4593 + 4594 + micromark-util-events-to-acorn@2.0.3: 4595 + dependencies: 4596 + '@types/estree': 1.0.8 4597 + '@types/unist': 3.0.3 4598 + devlop: 1.1.0 4599 + estree-util-visit: 2.0.0 4600 + micromark-util-symbol: 2.0.1 4601 + micromark-util-types: 2.0.2 4602 + vfile-message: 4.0.3 4603 + 4604 + micromark-util-html-tag-name@2.0.1: {} 4605 + 4606 + micromark-util-normalize-identifier@2.0.1: 4607 + dependencies: 4608 + micromark-util-symbol: 2.0.1 4609 + 4610 + micromark-util-resolve-all@2.0.1: 4611 + dependencies: 4612 + micromark-util-types: 2.0.2 4613 + 4614 + micromark-util-sanitize-uri@2.0.1: 4615 + dependencies: 4616 + micromark-util-character: 2.1.1 4617 + micromark-util-encode: 2.0.1 4618 + micromark-util-symbol: 2.0.1 4619 + 4620 + micromark-util-subtokenize@2.1.0: 4621 + dependencies: 4622 + devlop: 1.1.0 4623 + micromark-util-chunked: 2.0.1 4624 + micromark-util-symbol: 2.0.1 4625 + micromark-util-types: 2.0.2 4626 + 4627 + micromark-util-symbol@2.0.1: {} 4628 + 4629 + micromark-util-types@2.0.2: {} 4630 + 4631 + micromark@4.0.2: 4632 + dependencies: 4633 + '@types/debug': 4.1.12 4634 + debug: 4.4.3 4635 + decode-named-character-reference: 1.3.0 4636 + devlop: 1.1.0 4637 + micromark-core-commonmark: 2.0.3 4638 + micromark-factory-space: 2.0.1 4639 + micromark-util-character: 2.1.1 4640 + micromark-util-chunked: 2.0.1 4641 + micromark-util-combine-extensions: 2.0.1 4642 + micromark-util-decode-numeric-character-reference: 2.0.2 4643 + micromark-util-encode: 2.0.1 4644 + micromark-util-normalize-identifier: 2.0.1 4645 + micromark-util-resolve-all: 2.0.1 4646 + micromark-util-sanitize-uri: 2.0.1 4647 + micromark-util-subtokenize: 2.1.0 4648 + micromark-util-symbol: 2.0.1 4649 + micromark-util-types: 2.0.2 4650 + transitivePeerDependencies: 4651 + - supports-color 4652 + 4653 + mlly@1.8.0: 4654 + dependencies: 4655 + acorn: 8.16.0 4656 + pathe: 2.0.3 4657 + pkg-types: 1.3.1 4658 + ufo: 1.6.3 4659 + 4660 + mrmime@2.0.1: {} 4661 + 4662 + ms@2.1.3: {} 4663 + 4664 + nanoid@3.3.11: {} 4665 + 4666 + neotraverse@0.6.18: {} 4667 + 4668 + nlcst-to-string@4.0.0: 4669 + dependencies: 4670 + '@types/nlcst': 2.0.3 4671 + 4672 + node-fetch-native@1.6.7: {} 4673 + 4674 + node-mock-http@1.0.4: {} 4675 + 4676 + normalize-path@3.0.0: {} 4677 + 4678 + nth-check@2.1.1: 4679 + dependencies: 4680 + boolbase: 1.0.0 4681 + 4682 + ofetch@1.5.1: 4683 + dependencies: 4684 + destr: 2.0.5 4685 + node-fetch-native: 1.6.7 4686 + ufo: 1.6.3 4687 + 4688 + ohash@2.0.11: {} 4689 + 4690 + oniguruma-parser@0.12.1: {} 4691 + 4692 + oniguruma-to-es@4.3.4: 4693 + dependencies: 4694 + oniguruma-parser: 0.12.1 4695 + regex: 6.1.0 4696 + regex-recursion: 6.0.2 4697 + 4698 + p-limit@6.2.0: 4699 + dependencies: 4700 + yocto-queue: 1.2.2 4701 + 4702 + p-queue@8.1.1: 4703 + dependencies: 4704 + eventemitter3: 5.0.4 4705 + p-timeout: 6.1.4 4706 + 4707 + p-timeout@6.1.4: {} 4708 + 4709 + package-manager-detector@1.6.0: {} 4710 + 4711 + pagefind@1.4.0: 4712 + optionalDependencies: 4713 + '@pagefind/darwin-arm64': 1.4.0 4714 + '@pagefind/darwin-x64': 1.4.0 4715 + '@pagefind/freebsd-x64': 1.4.0 4716 + '@pagefind/linux-arm64': 1.4.0 4717 + '@pagefind/linux-x64': 1.4.0 4718 + '@pagefind/windows-x64': 1.4.0 4719 + 4720 + parse-entities@4.0.2: 4721 + dependencies: 4722 + '@types/unist': 2.0.11 4723 + character-entities-legacy: 3.0.0 4724 + character-reference-invalid: 2.0.1 4725 + decode-named-character-reference: 1.3.0 4726 + is-alphanumerical: 2.0.1 4727 + is-decimal: 2.0.1 4728 + is-hexadecimal: 2.0.1 4729 + 4730 + parse-latin@7.0.0: 4731 + dependencies: 4732 + '@types/nlcst': 2.0.3 4733 + '@types/unist': 3.0.3 4734 + nlcst-to-string: 4.0.0 4735 + unist-util-modify-children: 4.0.0 4736 + unist-util-visit-children: 3.0.0 4737 + vfile: 6.0.3 4738 + 4739 + parse5@7.3.0: 4740 + dependencies: 4741 + entities: 6.0.1 4742 + 4743 + path-data-parser@0.1.0: {} 4744 + 4745 + pathe@2.0.3: {} 4746 + 4747 + piccolore@0.1.3: {} 4748 + 4749 + picocolors@1.1.1: {} 4750 + 4751 + picomatch@2.3.1: {} 4752 + 4753 + picomatch@4.0.3: {} 4754 + 4755 + pkg-types@1.3.1: 4756 + dependencies: 4757 + confbox: 0.1.8 4758 + mlly: 1.8.0 4759 + pathe: 2.0.3 4760 + 4761 + points-on-curve@0.2.0: {} 4762 + 4763 + points-on-path@0.2.1: 4764 + dependencies: 4765 + path-data-parser: 0.1.0 4766 + points-on-curve: 0.2.0 4767 + 4768 + postcss-nested@6.2.0(postcss@8.5.6): 4769 + dependencies: 4770 + postcss: 8.5.6 4771 + postcss-selector-parser: 6.1.2 4772 + 4773 + postcss-selector-parser@6.1.2: 4774 + dependencies: 4775 + cssesc: 3.0.0 4776 + util-deprecate: 1.0.2 4777 + 4778 + postcss@8.5.6: 4779 + dependencies: 4780 + nanoid: 3.3.11 4781 + picocolors: 1.1.1 4782 + source-map-js: 1.2.1 4783 + 4784 + prismjs@1.30.0: {} 4785 + 4786 + prompts@2.4.2: 4787 + dependencies: 4788 + kleur: 3.0.3 4789 + sisteransi: 1.0.5 4790 + 4791 + property-information@7.1.0: {} 4792 + 4793 + radix3@1.1.2: {} 4794 + 4795 + readdirp@5.0.0: {} 4796 + 4797 + recma-build-jsx@1.0.0: 4798 + dependencies: 4799 + '@types/estree': 1.0.8 4800 + estree-util-build-jsx: 3.0.1 4801 + vfile: 6.0.3 4802 + 4803 + recma-jsx@1.0.1(acorn@8.16.0): 4804 + dependencies: 4805 + acorn: 8.16.0 4806 + acorn-jsx: 5.3.2(acorn@8.16.0) 4807 + estree-util-to-js: 2.0.0 4808 + recma-parse: 1.0.0 4809 + recma-stringify: 1.0.0 4810 + unified: 11.0.5 4811 + 4812 + recma-parse@1.0.0: 4813 + dependencies: 4814 + '@types/estree': 1.0.8 4815 + esast-util-from-js: 2.0.1 4816 + unified: 11.0.5 4817 + vfile: 6.0.3 4818 + 4819 + recma-stringify@1.0.0: 4820 + dependencies: 4821 + '@types/estree': 1.0.8 4822 + estree-util-to-js: 2.0.0 4823 + unified: 11.0.5 4824 + vfile: 6.0.3 4825 + 4826 + regex-recursion@6.0.2: 4827 + dependencies: 4828 + regex-utilities: 2.3.0 4829 + 4830 + regex-utilities@2.3.0: {} 4831 + 4832 + regex@6.1.0: 4833 + dependencies: 4834 + regex-utilities: 2.3.0 4835 + 4836 + rehype-expressive-code@0.41.6: 4837 + dependencies: 4838 + expressive-code: 0.41.6 4839 + 4840 + rehype-format@5.0.1: 4841 + dependencies: 4842 + '@types/hast': 3.0.4 4843 + hast-util-format: 1.1.0 4844 + 4845 + rehype-parse@9.0.1: 4846 + dependencies: 4847 + '@types/hast': 3.0.4 4848 + hast-util-from-html: 2.0.3 4849 + unified: 11.0.5 4850 + 4851 + rehype-raw@7.0.0: 4852 + dependencies: 4853 + '@types/hast': 3.0.4 4854 + hast-util-raw: 9.1.0 4855 + vfile: 6.0.3 4856 + 4857 + rehype-recma@1.0.0: 4858 + dependencies: 4859 + '@types/estree': 1.0.8 4860 + '@types/hast': 3.0.4 4861 + hast-util-to-estree: 3.1.3 4862 + transitivePeerDependencies: 4863 + - supports-color 4864 + 4865 + rehype-stringify@10.0.1: 4866 + dependencies: 4867 + '@types/hast': 3.0.4 4868 + hast-util-to-html: 9.0.5 4869 + unified: 11.0.5 4870 + 4871 + rehype@13.0.2: 4872 + dependencies: 4873 + '@types/hast': 3.0.4 4874 + rehype-parse: 9.0.1 4875 + rehype-stringify: 10.0.1 4876 + unified: 11.0.5 4877 + 4878 + remark-directive@3.0.1: 4879 + dependencies: 4880 + '@types/mdast': 4.0.4 4881 + mdast-util-directive: 3.1.0 4882 + micromark-extension-directive: 3.0.2 4883 + unified: 11.0.5 4884 + transitivePeerDependencies: 4885 + - supports-color 4886 + 4887 + remark-gfm@4.0.1: 4888 + dependencies: 4889 + '@types/mdast': 4.0.4 4890 + mdast-util-gfm: 3.1.0 4891 + micromark-extension-gfm: 3.0.0 4892 + remark-parse: 11.0.0 4893 + remark-stringify: 11.0.0 4894 + unified: 11.0.5 4895 + transitivePeerDependencies: 4896 + - supports-color 4897 + 4898 + remark-mdx@3.1.1: 4899 + dependencies: 4900 + mdast-util-mdx: 3.0.0 4901 + micromark-extension-mdxjs: 3.0.0 4902 + transitivePeerDependencies: 4903 + - supports-color 4904 + 4905 + remark-parse@11.0.0: 4906 + dependencies: 4907 + '@types/mdast': 4.0.4 4908 + mdast-util-from-markdown: 2.0.2 4909 + micromark-util-types: 2.0.2 4910 + unified: 11.0.5 4911 + transitivePeerDependencies: 4912 + - supports-color 4913 + 4914 + remark-rehype@11.1.2: 4915 + dependencies: 4916 + '@types/hast': 3.0.4 4917 + '@types/mdast': 4.0.4 4918 + mdast-util-to-hast: 13.2.1 4919 + unified: 11.0.5 4920 + vfile: 6.0.3 4921 + 4922 + remark-smartypants@3.0.2: 4923 + dependencies: 4924 + retext: 9.0.0 4925 + retext-smartypants: 6.2.0 4926 + unified: 11.0.5 4927 + unist-util-visit: 5.1.0 4928 + 4929 + remark-stringify@11.0.0: 4930 + dependencies: 4931 + '@types/mdast': 4.0.4 4932 + mdast-util-to-markdown: 2.1.2 4933 + unified: 11.0.5 4934 + 4935 + retext-latin@4.0.0: 4936 + dependencies: 4937 + '@types/nlcst': 2.0.3 4938 + parse-latin: 7.0.0 4939 + unified: 11.0.5 4940 + 4941 + retext-smartypants@6.2.0: 4942 + dependencies: 4943 + '@types/nlcst': 2.0.3 4944 + nlcst-to-string: 4.0.0 4945 + unist-util-visit: 5.1.0 4946 + 4947 + retext-stringify@4.0.0: 4948 + dependencies: 4949 + '@types/nlcst': 2.0.3 4950 + nlcst-to-string: 4.0.0 4951 + unified: 11.0.5 4952 + 4953 + retext@9.0.0: 4954 + dependencies: 4955 + '@types/nlcst': 2.0.3 4956 + retext-latin: 4.0.0 4957 + retext-stringify: 4.0.0 4958 + unified: 11.0.5 4959 + 4960 + robust-predicates@3.0.2: {} 4961 + 4962 + rollup@4.57.1: 4963 + dependencies: 4964 + '@types/estree': 1.0.8 4965 + optionalDependencies: 4966 + '@rollup/rollup-android-arm-eabi': 4.57.1 4967 + '@rollup/rollup-android-arm64': 4.57.1 4968 + '@rollup/rollup-darwin-arm64': 4.57.1 4969 + '@rollup/rollup-darwin-x64': 4.57.1 4970 + '@rollup/rollup-freebsd-arm64': 4.57.1 4971 + '@rollup/rollup-freebsd-x64': 4.57.1 4972 + '@rollup/rollup-linux-arm-gnueabihf': 4.57.1 4973 + '@rollup/rollup-linux-arm-musleabihf': 4.57.1 4974 + '@rollup/rollup-linux-arm64-gnu': 4.57.1 4975 + '@rollup/rollup-linux-arm64-musl': 4.57.1 4976 + '@rollup/rollup-linux-loong64-gnu': 4.57.1 4977 + '@rollup/rollup-linux-loong64-musl': 4.57.1 4978 + '@rollup/rollup-linux-ppc64-gnu': 4.57.1 4979 + '@rollup/rollup-linux-ppc64-musl': 4.57.1 4980 + '@rollup/rollup-linux-riscv64-gnu': 4.57.1 4981 + '@rollup/rollup-linux-riscv64-musl': 4.57.1 4982 + '@rollup/rollup-linux-s390x-gnu': 4.57.1 4983 + '@rollup/rollup-linux-x64-gnu': 4.57.1 4984 + '@rollup/rollup-linux-x64-musl': 4.57.1 4985 + '@rollup/rollup-openbsd-x64': 4.57.1 4986 + '@rollup/rollup-openharmony-arm64': 4.57.1 4987 + '@rollup/rollup-win32-arm64-msvc': 4.57.1 4988 + '@rollup/rollup-win32-ia32-msvc': 4.57.1 4989 + '@rollup/rollup-win32-x64-gnu': 4.57.1 4990 + '@rollup/rollup-win32-x64-msvc': 4.57.1 4991 + fsevents: 2.3.3 4992 + 4993 + roughjs@4.6.6: 4994 + dependencies: 4995 + hachure-fill: 0.5.2 4996 + path-data-parser: 0.1.0 4997 + points-on-curve: 0.2.0 4998 + points-on-path: 0.2.1 4999 + 5000 + rw@1.3.3: {} 5001 + 5002 + safer-buffer@2.1.2: {} 5003 + 5004 + sax@1.4.4: {} 5005 + 5006 + semver@7.7.4: {} 5007 + 5008 + sharp@0.34.5: 5009 + dependencies: 5010 + '@img/colour': 1.0.0 5011 + detect-libc: 2.1.2 5012 + semver: 7.7.4 5013 + optionalDependencies: 5014 + '@img/sharp-darwin-arm64': 0.34.5 5015 + '@img/sharp-darwin-x64': 0.34.5 5016 + '@img/sharp-libvips-darwin-arm64': 1.2.4 5017 + '@img/sharp-libvips-darwin-x64': 1.2.4 5018 + '@img/sharp-libvips-linux-arm': 1.2.4 5019 + '@img/sharp-libvips-linux-arm64': 1.2.4 5020 + '@img/sharp-libvips-linux-ppc64': 1.2.4 5021 + '@img/sharp-libvips-linux-riscv64': 1.2.4 5022 + '@img/sharp-libvips-linux-s390x': 1.2.4 5023 + '@img/sharp-libvips-linux-x64': 1.2.4 5024 + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 5025 + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 5026 + '@img/sharp-linux-arm': 0.34.5 5027 + '@img/sharp-linux-arm64': 0.34.5 5028 + '@img/sharp-linux-ppc64': 0.34.5 5029 + '@img/sharp-linux-riscv64': 0.34.5 5030 + '@img/sharp-linux-s390x': 0.34.5 5031 + '@img/sharp-linux-x64': 0.34.5 5032 + '@img/sharp-linuxmusl-arm64': 0.34.5 5033 + '@img/sharp-linuxmusl-x64': 0.34.5 5034 + '@img/sharp-wasm32': 0.34.5 5035 + '@img/sharp-win32-arm64': 0.34.5 5036 + '@img/sharp-win32-ia32': 0.34.5 5037 + '@img/sharp-win32-x64': 0.34.5 5038 + 5039 + shiki@3.22.0: 5040 + dependencies: 5041 + '@shikijs/core': 3.22.0 5042 + '@shikijs/engine-javascript': 3.22.0 5043 + '@shikijs/engine-oniguruma': 3.22.0 5044 + '@shikijs/langs': 3.22.0 5045 + '@shikijs/themes': 3.22.0 5046 + '@shikijs/types': 3.22.0 5047 + '@shikijs/vscode-textmate': 10.0.2 5048 + '@types/hast': 3.0.4 5049 + 5050 + sisteransi@1.0.5: {} 5051 + 5052 + sitemap@8.0.2: 5053 + dependencies: 5054 + '@types/node': 17.0.45 5055 + '@types/sax': 1.2.7 5056 + arg: 5.0.2 5057 + sax: 1.4.4 5058 + 5059 + smol-toml@1.6.0: {} 5060 + 5061 + source-map-js@1.2.1: {} 5062 + 5063 + source-map@0.7.6: {} 5064 + 5065 + space-separated-tokens@2.0.2: {} 5066 + 5067 + stream-replace-string@2.0.0: {} 5068 + 5069 + string-width@4.2.3: 5070 + dependencies: 5071 + emoji-regex: 8.0.0 5072 + is-fullwidth-code-point: 3.0.0 5073 + strip-ansi: 6.0.1 5074 + 5075 + string-width@7.2.0: 5076 + dependencies: 5077 + emoji-regex: 10.6.0 5078 + get-east-asian-width: 1.5.0 5079 + strip-ansi: 7.1.2 5080 + 5081 + stringify-entities@4.0.4: 5082 + dependencies: 5083 + character-entities-html4: 2.1.0 5084 + character-entities-legacy: 3.0.0 5085 + 5086 + strip-ansi@6.0.1: 5087 + dependencies: 5088 + ansi-regex: 5.0.1 5089 + 5090 + strip-ansi@7.1.2: 5091 + dependencies: 5092 + ansi-regex: 6.2.2 5093 + 5094 + style-to-js@1.1.21: 5095 + dependencies: 5096 + style-to-object: 1.0.14 5097 + 5098 + style-to-object@1.0.14: 5099 + dependencies: 5100 + inline-style-parser: 0.2.7 5101 + 5102 + stylis@4.3.6: {} 5103 + 5104 + svgo@4.0.0: 5105 + dependencies: 5106 + commander: 11.1.0 5107 + css-select: 5.2.2 5108 + css-tree: 3.1.0 5109 + css-what: 6.2.2 5110 + csso: 5.0.5 5111 + picocolors: 1.1.1 5112 + sax: 1.4.4 5113 + 5114 + tiny-inflate@1.0.3: {} 5115 + 5116 + tinyexec@1.0.2: {} 5117 + 5118 + tinyglobby@0.2.15: 5119 + dependencies: 5120 + fdir: 6.5.0(picomatch@4.0.3) 5121 + picomatch: 4.0.3 5122 + 5123 + trim-lines@3.0.1: {} 5124 + 5125 + trough@2.2.0: {} 5126 + 5127 + ts-dedent@2.2.0: {} 5128 + 5129 + tsconfck@3.1.6(typescript@5.9.3): 5130 + optionalDependencies: 5131 + typescript: 5.9.3 5132 + 5133 + tslib@2.8.1: 5134 + optional: true 5135 + 5136 + type-fest@4.41.0: {} 5137 + 5138 + typescript@5.9.3: {} 5139 + 5140 + ufo@1.6.3: {} 5141 + 5142 + ultrahtml@1.6.0: {} 5143 + 5144 + uncrypto@0.1.3: {} 5145 + 5146 + unified@11.0.5: 5147 + dependencies: 5148 + '@types/unist': 3.0.3 5149 + bail: 2.0.2 5150 + devlop: 1.1.0 5151 + extend: 3.0.2 5152 + is-plain-obj: 4.1.0 5153 + trough: 2.2.0 5154 + vfile: 6.0.3 5155 + 5156 + unifont@0.7.4: 5157 + dependencies: 5158 + css-tree: 3.1.0 5159 + ofetch: 1.5.1 5160 + ohash: 2.0.11 5161 + 5162 + unist-util-find-after@5.0.0: 5163 + dependencies: 5164 + '@types/unist': 3.0.3 5165 + unist-util-is: 6.0.1 5166 + 5167 + unist-util-is@6.0.1: 5168 + dependencies: 5169 + '@types/unist': 3.0.3 5170 + 5171 + unist-util-modify-children@4.0.0: 5172 + dependencies: 5173 + '@types/unist': 3.0.3 5174 + array-iterate: 2.0.1 5175 + 5176 + unist-util-position-from-estree@2.0.0: 5177 + dependencies: 5178 + '@types/unist': 3.0.3 5179 + 5180 + unist-util-position@5.0.0: 5181 + dependencies: 5182 + '@types/unist': 3.0.3 5183 + 5184 + unist-util-remove-position@5.0.0: 5185 + dependencies: 5186 + '@types/unist': 3.0.3 5187 + unist-util-visit: 5.1.0 5188 + 5189 + unist-util-stringify-position@4.0.0: 5190 + dependencies: 5191 + '@types/unist': 3.0.3 5192 + 5193 + unist-util-visit-children@3.0.0: 5194 + dependencies: 5195 + '@types/unist': 3.0.3 5196 + 5197 + unist-util-visit-parents@6.0.2: 5198 + dependencies: 5199 + '@types/unist': 3.0.3 5200 + unist-util-is: 6.0.1 5201 + 5202 + unist-util-visit@5.1.0: 5203 + dependencies: 5204 + '@types/unist': 3.0.3 5205 + unist-util-is: 6.0.1 5206 + unist-util-visit-parents: 6.0.2 5207 + 5208 + unstorage@1.17.4: 5209 + dependencies: 5210 + anymatch: 3.1.3 5211 + chokidar: 5.0.0 5212 + destr: 2.0.5 5213 + h3: 1.15.5 5214 + lru-cache: 11.2.6 5215 + node-fetch-native: 1.6.7 5216 + ofetch: 1.5.1 5217 + ufo: 1.6.3 5218 + 5219 + util-deprecate@1.0.2: {} 5220 + 5221 + uuid@11.1.0: {} 5222 + 5223 + vfile-location@5.0.3: 5224 + dependencies: 5225 + '@types/unist': 3.0.3 5226 + vfile: 6.0.3 5227 + 5228 + vfile-message@4.0.3: 5229 + dependencies: 5230 + '@types/unist': 3.0.3 5231 + unist-util-stringify-position: 4.0.0 5232 + 5233 + vfile@6.0.3: 5234 + dependencies: 5235 + '@types/unist': 3.0.3 5236 + vfile-message: 4.0.3 5237 + 5238 + vite@6.4.1: 5239 + dependencies: 5240 + esbuild: 0.25.12 5241 + fdir: 6.5.0(picomatch@4.0.3) 5242 + picomatch: 4.0.3 5243 + postcss: 8.5.6 5244 + rollup: 4.57.1 5245 + tinyglobby: 0.2.15 5246 + optionalDependencies: 5247 + fsevents: 2.3.3 5248 + 5249 + vitefu@1.1.1(vite@6.4.1): 5250 + optionalDependencies: 5251 + vite: 6.4.1 5252 + 5253 + vscode-jsonrpc@8.2.0: {} 5254 + 5255 + vscode-languageserver-protocol@3.17.5: 5256 + dependencies: 5257 + vscode-jsonrpc: 8.2.0 5258 + vscode-languageserver-types: 3.17.5 5259 + 5260 + vscode-languageserver-textdocument@1.0.12: {} 5261 + 5262 + vscode-languageserver-types@3.17.5: {} 5263 + 5264 + vscode-languageserver@9.0.1: 5265 + dependencies: 5266 + vscode-languageserver-protocol: 3.17.5 5267 + 5268 + vscode-uri@3.1.0: {} 5269 + 5270 + web-namespaces@2.0.1: {} 5271 + 5272 + which-pm-runs@1.1.0: {} 5273 + 5274 + widest-line@5.0.0: 5275 + dependencies: 5276 + string-width: 7.2.0 5277 + 5278 + wrap-ansi@9.0.2: 5279 + dependencies: 5280 + ansi-styles: 6.2.3 5281 + string-width: 7.2.0 5282 + strip-ansi: 7.1.2 5283 + 5284 + xxhash-wasm@1.1.0: {} 5285 + 5286 + yargs-parser@21.1.1: {} 5287 + 5288 + yocto-queue@1.2.2: {} 5289 + 5290 + yocto-spinner@0.2.3: 5291 + dependencies: 5292 + yoctocolors: 2.1.2 5293 + 5294 + yoctocolors@2.1.2: {} 5295 + 5296 + zod-to-json-schema@3.25.1(zod@3.25.76): 5297 + dependencies: 5298 + zod: 3.25.76 5299 + 5300 + zod-to-ts@1.2.0(typescript@5.9.3)(zod@3.25.76): 5301 + dependencies: 5302 + typescript: 5.9.3 5303 + zod: 3.25.76 5304 + 5305 + zod@3.25.76: {} 5306 + 5307 + zwitch@2.0.4: {}
+1
docs/public/favicon.svg
··· 1 + <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128"><path fill-rule="evenodd" d="M81 36 64 0 47 36l-1 2-9-10a6 6 0 0 0-9 9l10 10h-2L0 64l36 17h2L28 91a6 6 0 1 0 9 9l9-10 1 2 17 36 17-36v-2l9 10a6 6 0 1 0 9-9l-9-9 2-1 36-17-36-17-2-1 9-9a6 6 0 1 0-9-9l-9 10v-2Zm-17 2-2 5c-4 8-11 15-19 19l-5 2 5 2c8 4 15 11 19 19l2 5 2-5c4-8 11-15 19-19l5-2-5-2c-8-4-15-11-19-19l-2-5Z" clip-rule="evenodd"/><path d="M118 19a6 6 0 0 0-9-9l-3 3a6 6 0 1 0 9 9l3-3Zm-96 4c-2 2-6 2-9 0l-3-3a6 6 0 1 1 9-9l3 3c3 2 3 6 0 9Zm0 82c-2-2-6-2-9 0l-3 3a6 6 0 1 0 9 9l3-3c3-2 3-6 0-9Zm96 4a6 6 0 0 1-9 9l-3-3a6 6 0 1 1 9-9l3 3Z"/><style>path{fill:#000}@media (prefers-color-scheme:dark){path{fill:#fff}}</style></svg>
docs/src/assets/houston.webp

This is a binary file and will not be displayed.

+7
docs/src/content.config.ts
··· 1 + import { defineCollection } from 'astro:content'; 2 + import { docsLoader } from '@astrojs/starlight/loaders'; 3 + import { docsSchema } from '@astrojs/starlight/schema'; 4 + 5 + export const collections = { 6 + docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }), 7 + };
+63
docs/src/content/docs/community.md
··· 1 + --- 2 + title: Community 3 + description: Get help, share your work, and contribute to Den. 4 + --- 5 + 6 + ## Get Support 7 + 8 + - [GitHub Discussions](https://github.com/vic/den/discussions) — ask questions, share ideas 9 + - [Zulip Chat](https://oeiuwq.zulipchat.com/#narrow/channel/548534-den) — real-time help 10 + - [Matrix Channel](https://matrix.to/#/#den-lib:matrix.org) — chat with the community 11 + 12 + Everyone is welcome. The only rule: be mindful and respectful. 13 + 14 + ## Real-World Examples 15 + 16 + - [`vic/vix`](https://github.com/vic/vix) — Den author's personal infra 17 + - [`quasigod.xyz/nixconfig`](https://tangled.org/quasigod.xyz/nixconfig) 18 + - [GitHub Search](https://github.com/search?q=vic%2Fden+language%3ANix&type=code) — find more 19 + 20 + ## Contributing 21 + 22 + All contributions welcome. PRs are checked by CI. 23 + 24 + ### Run Tests 25 + 26 + ```console 27 + nix flake check github:vic/checkmate --override-input target . 28 + ``` 29 + 30 + ### Format Code 31 + 32 + ```console 33 + nix run github:vic/checkmate#fmt --override-input target . 34 + ``` 35 + 36 + ### Report Bugs 37 + 38 + Use the `bogus` template to create a minimal reproduction: 39 + 40 + ```console 41 + mkdir bogus && cd bogus 42 + nix flake init -t github:vic/den#bogus 43 + nix flake update den 44 + nix flake check 45 + ``` 46 + 47 + Share your repository with us on [Discussions](https://github.com/vic/den/discussions). 48 + 49 + ## Ecosystem 50 + 51 + - [flake-aspects](https://github.com/vic/flake-aspects) — aspect composition library 52 + - [import-tree](https://github.com/vic/import-tree) — recursive module imports 53 + - [denful](https://github.com/vic/denful) — community aspect distribution 54 + - [dendrix](https://dendrix.oeiuwq.com/) — index of dendritic aspects 55 + - [Dendritic Design](https://github.com/mightyiam/dendritic) — the pattern that inspired Den 56 + 57 + ## Sponsor 58 + 59 + Den is made with love by [vic](https://bsky.app/profile/oeiuwq.bsky.social). 60 + 61 + If you find Den useful, consider [sponsoring](https://github.com/sponsors/vic). 62 + 63 + > *Quaerendo Invenietis* — Seek and ye shall find.
+148
docs/src/content/docs/explanation/aspects.md
··· 1 + --- 2 + title: Aspects & Functors 3 + description: How aspects use the __functor pattern for context-awareness. 4 + --- 5 + 6 + import { Aside } from '@astrojs/starlight/components'; 7 + 8 + <Aside type="tip">Source: [`nix/lib.nix`](https://github.com/vic/den/blob/main/nix/lib.nix) · Built on [flake-aspects](https://github.com/vic/flake-aspects)</Aside> 9 + 10 + ## The __functor Pattern 11 + 12 + In Nix, any attribute set with `__functor` can be called as a function: 13 + 14 + ```nix 15 + let 16 + counter = { 17 + value = 42; 18 + __functor = self: n: self.value + n; 19 + }; 20 + in counter 8 # => 50 21 + ``` 22 + 23 + The `__functor` receives `self` (the attrset) and an argument. 24 + 25 + ## Aspects as Functors 26 + 27 + Every aspect in `flake-aspects` has a default `__functor`: 28 + 29 + ```nix 30 + { 31 + nixos = { a = 1; }; 32 + __functor = self: _context: self; # ignores context 33 + } 34 + ``` 35 + 36 + By default, it ignores context and returns itself. But you can replace 37 + `__functor` with one that **inspects** context: 38 + 39 + ```nix 40 + { 41 + nixos.foo = 24; 42 + __functor = self: context: 43 + if context ? host 44 + then self 45 + else { includes = [ fallback ]; }; 46 + } 47 + ``` 48 + 49 + ## Aspect Structure 50 + 51 + Aspects have three kinds of attributes: 52 + 53 + ### Owned Configurations 54 + 55 + Direct class settings: 56 + 57 + ```nix 58 + den.aspects.igloo = { 59 + nixos.networking.hostName = "igloo"; 60 + darwin.nix-homebrew.enable = true; 61 + homeManager.programs.vim.enable = true; 62 + }; 63 + ``` 64 + 65 + ### Includes 66 + 67 + Dependencies on other aspects — a directed graph: 68 + 69 + ```nix 70 + den.aspects.igloo.includes = [ 71 + den.aspects.gaming 72 + den.aspects.tools._.editors 73 + ({ host, ... }: { nixos.time.timeZone = "UTC"; }) 74 + ]; 75 + ``` 76 + 77 + Includes can be: 78 + - **Static aspects** — always included 79 + - **Functions** — called with context, included when they match 80 + 81 + ### Provides 82 + 83 + Nested sub-aspects forming a tree: 84 + 85 + ```nix 86 + den.aspects.gaming.provides.emulation = { 87 + nixos.programs.retroarch.enable = true; 88 + }; 89 + # Access: den.aspects.gaming._.emulation 90 + ``` 91 + 92 + ## Resolution 93 + 94 + When Den needs a NixOS module from an aspect, it calls `.resolve`: 95 + 96 + ```nix 97 + module = den.aspects.igloo.resolve { 98 + class = "nixos"; 99 + aspect-chain = []; 100 + }; 101 + ``` 102 + 103 + ```mermaid 104 + graph TD 105 + Asp["den.aspects.igloo"] 106 + Asp --> Owned["owned: nixos, darwin, homeManager"] 107 + Asp --> Inc["includes: gaming, tools._.editors, fn..."] 108 + Asp --> Resolve[".resolve { class = 'nixos' }"] 109 + Resolve --> Collect["Collect all 'nixos' attrs<br/>from aspect + transitive includes"] 110 + Collect --> Module["Single merged Nix module"] 111 + ``` 112 + 113 + This collects all `nixos` configs from the aspect and all its transitive 114 + includes into a single Nix module. 115 + 116 + ## Functions vs Aspects 117 + 118 + Functions in `includes` are **context-aware**: 119 + 120 + ```nix 121 + den.aspects.igloo.includes = [ 122 + # static — always included 123 + { homeManager.programs.direnv.enable = true; } 124 + 125 + # parametric — called with context 126 + ({ host, ... }: { nixos.time.timeZone = "UTC"; }) 127 + 128 + # conditional — only called when context has user 129 + ({ host, user, ... }: { 130 + homeManager.programs.git.userName = user.userName; 131 + }) 132 + ]; 133 + ``` 134 + 135 + Den inspects each function's **argument names** to decide whether to call 136 + it with the current context. See [Parametric Aspects](/explanation/parametric/) 137 + for the matching rules. 138 + 139 + ## The den.default Aspect 140 + 141 + [`den.default`](/explanation/context-pipeline/#dendefault-is-an-alias) is an aspect with `parametric.atLeast` functor: 142 + 143 + ```nix 144 + den.default = den.lib.parametric.atLeast { }; 145 + ``` 146 + 147 + It dispatches context to all its includes. Since every host, user, and 148 + home includes `den.default`, it serves as the backbone for global routing.
+214
docs/src/content/docs/explanation/context-pipeline.md
··· 1 + --- 2 + title: Context Pipeline 3 + description: The complete data flow from host declaration to final configuration. 4 + --- 5 + 6 + import { Aside } from '@astrojs/starlight/components'; 7 + 8 + <Aside type="tip">Source: [`modules/context/os.nix`](https://github.com/vic/den/blob/main/modules/context/os.nix) · [`modules/context/types.nix`](https://github.com/vic/den/blob/main/modules/context/types.nix) · HM: [`hm-os.nix`](https://github.com/vic/den/blob/main/modules/aspects/provides/home-manager/hm-os.nix) · [`hm-integration.nix`](https://github.com/vic/den/blob/main/modules/aspects/provides/home-manager/hm-integration.nix)</Aside> 9 + 10 + ## The Full Pipeline 11 + 12 + When Den evaluates a host configuration, data flows through a pipeline 13 + of context transformations. Here is the complete picture: 14 + 15 + ```mermaid 16 + graph TD 17 + Host["den.hosts.x86_64-linux.igloo"] 18 + Host -->|"creates"| CtxHost["ctx.host { host }"] 19 + 20 + CtxHost -->|"conf"| HA["den.aspects.igloo<br/>(fixedTo { host })"] 21 + CtxHost -->|"into.default"| CtxDef1["ctx.default { host }"] 22 + CtxHost -->|"into.user<br/>(per user)"| CtxUser["ctx.user { host, user }"] 23 + CtxHost -->|"into.hm-host<br/>(if HM detected)"| CtxHM["ctx.hm-host { host }"] 24 + 25 + CtxUser -->|"conf"| UA["den.aspects.tux<br/>(fixedTo { host, user })"] 26 + CtxUser -->|"into.default"| CtxDef2["ctx.default { host, user }"] 27 + 28 + CtxHM -->|"conf"| HMmod["Import HM module"] 29 + CtxHM -->|"into.hm-user<br/>(per HM user)"| CtxHMU["ctx.hm-user { host, user }"] 30 + 31 + CtxHMU -->|"forward homeManager<br/>into host"| FW["home-manager.users.tux"] 32 + 33 + CtxDef1 -->|"includes"| DI1["den.default.includes<br/>(host-context funcs)"] 34 + CtxDef2 -->|"includes"| DI2["den.default.includes<br/>(user-context funcs)"] 35 + ``` 36 + 37 + ## How a nixosConfiguration Is Built 38 + 39 + Here is the concrete path from a host declaration to a final NixOS configuration: 40 + 41 + ```nix 42 + # 1. The initial data is the host itself — nothing NixOS-specific yet. 43 + aspect = den.ctx.host { 44 + host = den.hosts.x86_64-linux.igloo; 45 + }; 46 + 47 + # 2. ctxApply produces an aspect that includes den.aspects.igloo 48 + # plus the entire transformation chain (users, HM, defaults). 49 + 50 + # 3. We enter the NixOS domain by resolving for the "nixos" class. 51 + nixosModule = aspect.resolve { class = "nixos"; }; 52 + 53 + # 4. Standard nixosSystem with the resolved module. 54 + nixosConfigurations.igloo = lib.nixosSystem { 55 + modules = [ nixosModule ]; 56 + }; 57 + ``` 58 + 59 + This same pattern works for any class — replace `"nixos"` with 60 + `"darwin"`, `"homeManager"`, or any custom class name. 61 + 62 + ## Stage by Stage 63 + 64 + ### 1. Host Entry 65 + 66 + Den reads `den.hosts.x86_64-linux.igloo` and creates the initial context: 67 + 68 + ```nix 69 + ctx.host { host = den.hosts.x86_64-linux.igloo; } 70 + ``` 71 + 72 + ### 2. Host Aspect Resolution 73 + 74 + `ctx.host.conf` locates `den.aspects.igloo` and fixes it to the host context. 75 + All owned configs and static includes from the host aspect are collected. 76 + 77 + ### 3. Default Context (host-level) 78 + 79 + `ctx.host.into.default` produces `{ host }` for `ctx.default`, which 80 + activates `den.default.includes` functions matching `{ host, ... }`. 81 + 82 + ### 4. User Enumeration 83 + 84 + `ctx.host.into.user` maps over `host.users`, producing one 85 + `ctx.user { host, user }` per user. 86 + 87 + ### 5. User Aspect Resolution 88 + 89 + `ctx.user.conf` locates both the user's aspect (`den.aspects.tux`) and the 90 + host's aspect, collecting contributions from both directions. 91 + 92 + ### 6. Default Context (user-level) 93 + 94 + `ctx.user.into.default` activates `den.default.includes` again, this time 95 + with `{ host, user }` — functions needing user context now match. 96 + 97 + ### 7. Home-Manager Detection 98 + 99 + `ctx.host.into.hm-host` checks if the host has users with `homeManager` 100 + class and a supported OS. If so, it activates `ctx.hm-host`. 101 + 102 + ### 8. HM Module Import 103 + 104 + `ctx.hm-host.conf` imports the Home-Manager NixOS/Darwin module. 105 + 106 + ### 9. HM User Forwarding 107 + 108 + For each HM user, `ctx.hm-user` uses `den._.forward` to take 109 + `homeManager` class configs and insert them into 110 + `home-manager.users.<name>` on the host. 111 + 112 + ## Home-Manager Detection Criteria 113 + 114 + `ctx.host.into.hm-host` does not always activate. It checks three conditions 115 + (see [`hm-os.nix`](https://github.com/vic/den/blob/main/modules/aspects/provides/home-manager/hm-os.nix)): 116 + 117 + 1. **OS class is supported** — the host's class is `nixos` or `darwin` 118 + 2. **HM users exist** — at least one user has `class = "homeManager"` 119 + 3. **HM module available** — `inputs.home-manager` exists, or the host has a custom `hm-module` 120 + 121 + All three must be true. Hosts without users, or with only non-HM users, 122 + skip the entire HM pipeline. 123 + 124 + ## Duplication Caveat with den.default 125 + 126 + `den.default` (alias for `den.ctx.default`) is included at **every** 127 + context stage — once for the host context and once per user context. 128 + This means: 129 + 130 + - **Owned** configs and **static** includes from `den.default` can appear 131 + multiple times in the final configuration 132 + - For `mkMerge`-compatible options (most NixOS options), this is harmless 133 + - For **list** options, you may get duplicate entries 134 + 135 + To avoid duplication, use `den.lib.take.exactly` to restrict which 136 + context stages a function matches: 137 + 138 + ```nix 139 + den.default.includes = [ 140 + (den.lib.take.exactly ({ host }: { nixos.x = 1; })) 141 + ]; 142 + ``` 143 + 144 + This function runs only in the `{ host }` context, not in `{ host, user }`. 145 + 146 + :::tip 147 + Prefer attaching configurations directly to host or user aspects, or use 148 + `den.ctx.host` / `den.ctx.user` includes, rather than overloading `den.default` 149 + for everything. 150 + ::: 151 + 152 + ## Standalone Home-Manager 153 + 154 + For `den.homes`, the pipeline is shorter: 155 + 156 + ```mermaid 157 + graph TD 158 + Home["den.homes.x86_64-linux.tux"] 159 + Home -->|"creates"| CtxHome["ctx.home { home }"] 160 + CtxHome -->|"conf"| HomeA["den.aspects.tux<br/>(fixedTo { home })"] 161 + CtxHome -->|"into.default"| CtxDef["ctx.default { home }"] 162 + ``` 163 + 164 + ## den.default Is an Alias 165 + 166 + `den.default` is an alias for `den.ctx.default`. When you write: 167 + 168 + ```nix 169 + den.default.homeManager.home.stateVersion = "25.11"; 170 + den.default.includes = [ den._.define-user ]; 171 + ``` 172 + 173 + You are actually setting `den.ctx.default.homeManager...` and 174 + `den.ctx.default.includes`. This means `den.default` is a full 175 + context type — it has `conf`, `into`, `includes`, and owned attributes. 176 + 177 + ### How den.default Receives Data 178 + 179 + Host, user, and home aspects **do not** include `den.default` directly. 180 + Instead, each context type transforms **into** `default`: 181 + 182 + ```nix 183 + den.ctx.host.into.default = lib.singleton; # passes { host } 184 + den.ctx.user.into.default = lib.singleton; # passes { host, user } 185 + den.ctx.home.into.default = lib.singleton; # passes { home } 186 + ``` 187 + 188 + This means `den.default` is reached through the declarative context 189 + pipeline, not by direct inclusion. The data flowing into `den.default` 190 + is whatever the source context provides. 191 + 192 + ### Best Practices 193 + 194 + `den.default` is useful for global settings like `home.stateVersion`. 195 + However, prefer attaching parametric includes to the appropriate 196 + context type instead: 197 + 198 + | Instead of | Use | 199 + |-----------|-----| 200 + | `den.default.includes = [ hostFunc ]` | `den.ctx.host.includes = [ hostFunc ]` | 201 + | `den.default.includes = [ hmFunc ]` | `den.ctx.hm-host.includes = [ hmFunc ]` | 202 + | `den.default.nixos.x = 1` | `den.ctx.host.nixos.x = 1` | 203 + 204 + ## Why This Design? 205 + 206 + Each context type is **independent** and **composable**. You can: 207 + 208 + - Add new context types without modifying existing ones 209 + - Attach aspects to any stage of the pipeline 210 + - Create custom transformations for domain-specific needs 211 + - Override any built-in context behavior 212 + 213 + The pipeline is not hardcoded — it's declared through `den.ctx` definitions 214 + that you can inspect, extend, and customize.
+225
docs/src/content/docs/explanation/context-system.md
··· 1 + --- 2 + title: Context System 3 + description: How den.ctx defines, transforms, and propagates context. 4 + --- 5 + 6 + 7 + > Use the Source, Luke: [`modules/context/types.nix`](https://github.com/vic/den/blob/main/modules/context/types.nix) · [`modules/context/os.nix`](https://github.com/vic/den/blob/main/modules/context/os.nix) 8 + 9 + ## What Is a Context? 10 + 11 + In Den, a **context** is an attribute set whose **names** (not values) determine 12 + which functions get called. When Den applies a context `{ host, user }` to a 13 + function `{ host, ... }: ...`, the function matches. A function `{ never }: ...` 14 + does not match and is ignored. 15 + 16 + ## Why Named Contexts? 17 + 18 + Named contexts `ctx.host { host }` and `ctx.hm-host { host }` 19 + hold the same data, but `hm-host` **guarantees** that home-manager support was 20 + validated. This follows the [**parse-don't-validate**](https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/) principle: you cannot 21 + obtain an `hm-host` context unless all detection criteria passed. 22 + 23 + ```mermaid 24 + graph LR 25 + H["den.ctx.host {host}"] -->|"hm-detect"| Check{"host OS supported by HM?<br/>host has HM users?<br/>inputs.home-manager exists?"} 26 + Check -->|"all true"| HMH["same data {host}<br/>as den.ctx.hm-host"] 27 + Check -->|"any false"| Skip["∅ skipped"] 28 + HMH -->|"guaranteed"| Use["HM pipeline<br/>proceeds safely"] 29 + ``` 30 + 31 + ## Context Types: den.ctx 32 + 33 + Each context type is defined in `den.ctx` with four components: 34 + 35 + ```nix 36 + den.ctx.foobar = { 37 + desc = "The {foo, bar} context"; 38 + conf = { foo, bar }: den.aspects.${foo}._.${bar}; 39 + includes = [ /* parametric aspects */ ]; 40 + into = { 41 + baz = { foo, bar }: [{ baz = computeBaz foo bar; }]; 42 + }; 43 + }; 44 + ``` 45 + 46 + | Component | Purpose | 47 + |-----------|---------| 48 + | `desc` | Human-readable description | 49 + | `conf` | Given context values, locate the configuration aspect | 50 + | `includes` | Parametric aspects activated for this context (aspect cutting-point) | 51 + | `into` | Transformations fan-out to other context types | 52 + 53 + ## Context Application 54 + 55 + A context type is callable — it's a functor: 56 + 57 + ```nix 58 + aspect = den.ctx.foobar { foo = "hello"; bar = "world"; }; 59 + ``` 60 + 61 + When applied, Den: 62 + 63 + 1. **Produces owned configs** from the context type itself 64 + 2. **Locates the aspect** via `conf` (e.g., `den.aspects.hello._.world`) 65 + 3. **Applies includes** — parametric aspects matching this context 66 + 4. **Transforms** — calls each `into` function, producing new contexts 67 + 5. **Recurses** — applies each produced context through its own pipeline 68 + 69 + ```mermaid 70 + graph TD 71 + Apply["ctx.foobar { foo, bar }"] 72 + Apply --> Own["Owned configs"] 73 + Apply --> Conf["conf → locate aspect"] 74 + Apply --> Inc["includes → parametric aspects"] 75 + Apply --> Into["into.baz → new contexts"] 76 + Into --> Next["ctx.baz { baz }"] 77 + Next --> Own2["...recurse"] 78 + ``` 79 + 80 + ## Transformation Types 81 + 82 + Transformations have the type `source → [ target ]` — they return a **list**. 83 + This enables two patterns: 84 + 85 + ```mermaid 86 + graph TD 87 + subgraph "Fan-out (one → many)" 88 + Host1["{host}"] -->|"into.user"| U1["{host, user₁}"] 89 + Host1 -->|"into.user"| U2["{host, user₂}"] 90 + Host1 -->|"into.user"| U3["{host, user₃}"] 91 + end 92 + subgraph "Conditional (one → zero or one)" 93 + Host2["{host}"] -->|"into.hm-host"| Gate{"detection<br/>gate"} 94 + Gate -->|"passes"| HM["{host} as hm-host"] 95 + Gate -->|"fails"| Empty["∅ empty list"] 96 + end 97 + ``` 98 + 99 + **Fan-out** — one context producing many: 100 + 101 + ```nix 102 + den.ctx.host.into.user = { host }: 103 + map (user: { inherit host user; }) (attrValues host.users); 104 + ``` 105 + 106 + One host fans out to N user contexts. 107 + 108 + **Conditional propagation** — zero or one: 109 + 110 + ```nix 111 + den.ctx.host.into.hm-host = { host }: 112 + lib.optional (isHmSupported host) { inherit host; }; 113 + ``` 114 + 115 + If the condition fails, the list is empty and no `hm-host` context is created. 116 + The data is the same `{ host }`, but the named context guarantees the validation 117 + passed. 118 + 119 + ## Contexts as Aspect Cutting-Points 120 + 121 + Contexts are aspect-like themselves. They have owned configs and `.includes`: 122 + 123 + ```nix 124 + den.ctx.hm-host.nixos.home-manager.useGlobalPkgs = true; 125 + 126 + den.ctx.hm-host.includes = [ 127 + ({ host, ... }: { nixos.home-manager.backupFileExtension = "bak"; }) 128 + ]; 129 + ``` 130 + 131 + This is like `den.default.includes` **but scoped** — it only activates for 132 + hosts with validated home-manager support. Use context includes to attach 133 + aspects to specific pipeline stages instead of the catch-all `den.default`. 134 + 135 + ## Extending Context Flow 136 + 137 + Add new transformations to existing context types from any module: 138 + 139 + ```nix 140 + den.ctx.hm-host.into.foo = { host }: [ { foo = host.name; } ]; 141 + den.ctx.foo.conf = { foo }: { funny.names = [ foo ]; }; 142 + ``` 143 + 144 + The module system merges these definitions. You can extend the pipeline 145 + without modifying any built-in file. 146 + 147 + ## Built-in Context Types 148 + 149 + Den defines these context types for its NixOS/Darwin/HM framework: 150 + 151 + ### host — `{ host }` 152 + 153 + The entry point. Created when evaluating `den.hosts.<system>.<name>`: 154 + 155 + ```nix 156 + den.ctx.host.conf = { host }: 157 + parametric.fixedTo { inherit host; } den.aspects.${host.aspect}; 158 + 159 + den.ctx.host.into.default = lib.singleton; 160 + den.ctx.host.into.user = { host }: 161 + map (user: { inherit host user; }) (attrValues host.users); 162 + ``` 163 + 164 + Transforms **into** `default` (for global aspects) and `user` (for each user). 165 + 166 + ### user — `{ host, user }` 167 + 168 + Created for each user on a host: 169 + 170 + ```nix 171 + den.ctx.user.conf = { host, user }@ctx: { 172 + includes = [ 173 + (fixedTo ctx userAspect) 174 + (atLeast hostAspect ctx) 175 + ]; 176 + }; 177 + 178 + den.ctx.user.into.default = lib.singleton; 179 + ``` 180 + 181 + ### default — catch-all 182 + 183 + `den.default` is an alias for `den.ctx.default`. Every context type 184 + transforms into `default` via `.into.default`: 185 + 186 + ```nix 187 + den.ctx.default.conf = _: { }; 188 + ``` 189 + 190 + This is how `den.default.includes` functions receive their context data — 191 + host, user, or home contexts all flow through here. 192 + 193 + ### hm-host — `{ host }` (when HM detected) 194 + 195 + Activates only for hosts with Home-Manager users. Imports the HM module. 196 + See [Context Pipeline](/explanation/context-pipeline/) for detection criteria. 197 + 198 + ### hm-user — `{ host, user }` (HM users) 199 + 200 + Created for each HM user, forwards `homeManager` class into the host. 201 + 202 + ### home — `{ home }` (standalone HM) 203 + 204 + Entry point for standalone Home-Manager configurations. 205 + 206 + ## Custom Context Types 207 + 208 + Create your own for domain-specific pipelines: 209 + 210 + ```nix 211 + den.ctx.greeting.conf = { hello }: 212 + { funny.names = [ hello ]; }; 213 + 214 + den.ctx.greeting.into.shout = { hello }: 215 + [{ shout = lib.toUpper hello; }]; 216 + 217 + den.ctx.shout.conf = { shout }: 218 + { funny.names = [ shout ]; }; 219 + ``` 220 + 221 + Applying `den.ctx.greeting { hello = "world"; }` produces both 222 + `"world"` and `"WORLD"` through the transformation chain. 223 + 224 + See the [Context Pipeline](/explanation/context-pipeline/) for the complete data flow. 225 + See the [`den.ctx` Reference](/reference/ctx/) for all built-in types.
+86
docs/src/content/docs/explanation/core-principles.md
··· 1 + --- 2 + title: Core Principles 3 + description: The two fundamental ideas that make Den unique. 4 + --- 5 + 6 + ## The Two Pillars 7 + 8 + Den is built on two intertwined principles that together enable a new way 9 + of thinking about Nix configurations: 10 + 11 + ```mermaid 12 + graph LR 13 + subgraph "1. Context Transformation" 14 + CT["Declarative context shapes"] --> TP["Pipeline of context transformations"] 15 + end 16 + subgraph "2. Context-Aware Aspects" 17 + CA["Functions of context"] --> CP["Provide Conditional Configs"] 18 + end 19 + CT -.-> CA 20 + CA -.-> CT 21 + ``` 22 + 23 + ### 1. Context Transformation 24 + 25 + Traditional Nix setups wire modules directly: this NixOS module imports 26 + that file, this Home-Manager config hardcodes that username. 27 + 28 + Den replaces this with a **declarative pipeline**. You declare entities 29 + (hosts, users, homes) and context types (shapes holding them). Den transforms these through 30 + a graph of context stages, each producing richer or conditioned data. 31 + 32 + The key insight: **the flow of data is declared separately from the 33 + configurations it produces**. 34 + 35 + ### 2. Context-Aware Aspects 36 + 37 + Aspects are not just bundles of configs — they are **functions** that inspect 38 + context to decide what to produce. A function taking `{ host, user }` naturally 39 + adapts to every host-user combination. A function requiring `{ other }` is 40 + not used. 41 + 42 + The key insight: **the shape of the function arguments determines when 43 + configs are produced, without explicit conditionals**. 44 + 45 + ## Why This Matters 46 + 47 + ### Re-usability 48 + 49 + An aspect like [`define-user`](/reference/batteries/#define-user) works on NixOS, Darwin, and standalone 50 + Home-Manager — not because it checks the platform, but because it produces 51 + configs for multiple classes and Den picks the relevant class module according to the configuration domain: 52 + 53 + ```nix 54 + { host, user, ... }: { 55 + nixos.users.users.${user.userName}.isNormalUser = true; 56 + darwin.users.users.${user.userName}.home = "/Users/${user.userName}"; 57 + homeManager.home.username = user.userName; 58 + } 59 + ``` 60 + 61 + ### Composability 62 + 63 + Aspects compose through `includes` — a directed dependency graph. 64 + The [`parametric`](/explanation/parametric/) functor ensures context flows through the entire graph: 65 + 66 + ```mermaid 67 + graph TD 68 + D["den.my-laptop"] --> WS["workspace"] 69 + D --> DU["common-users-env"] 70 + WS --> VPN["vpn"] 71 + WS --> DEV["dev-tools"] 72 + U["den.aspects.vic"] --> PU["primary-user"] 73 + U --> SH["user-shell 'fish'"] 74 + ``` 75 + 76 + ### Separation of Concerns 77 + 78 + Each Dendritic file is focused on a single responsability. Configuring it across all different domains. Configurations are parametrized by data outside of their module config. 79 + 80 + ## The Result 81 + 82 + A system where: 83 + - **Declaring** entities is separate from **configuring** them 84 + - **Configurations** are separate from **when they apply** 85 + - [**Aspects**](/explanation/aspects/) compose without knowing each other’s details 86 + - [**Context**](/explanation/context-system/) flows declaratively through a [typed pipeline](/explanation/context-pipeline/)
+125
docs/src/content/docs/explanation/library-vs-framework.md
··· 1 + --- 2 + title: Library vs Framework 3 + description: Understanding Den's dual nature as both a library and a framework. 4 + --- 5 + 6 + ## Den the Library 7 + 8 + At its core, Den is a **library** for context-driven Nix configurations. 9 + The library provides: 10 + 11 + - [**`den.ctx`**](/reference/ctx/) — Declarative context types with transformations 12 + - [**`den.lib.parametric`**](/reference/lib/#denlibparametric) — Functors for context-aware dispatch 13 + - [**`den.lib.take`**](/reference/lib/#denlibtake) — Argument matching (`atLeast`, `exactly`) 14 + - [**`den.lib.aspects`**](/reference/lib/#denlibaspects) — Aspect composition (via [flake-aspects](https://github.com/vic/flake-aspects)) 15 + - **`den.lib.canTake`** — Function signature introspection 16 + - [**`den.lib.__findFile`**](/guides/angle-brackets/) — Angle-bracket resolution 17 + 18 + These tools work with **any Nix class**. You can define context types 19 + for terraform modules, NixVim configs, container definitions, or anything 20 + else configurable through Nix. 21 + 22 + ```mermaid 23 + graph LR 24 + subgraph "Den Library" 25 + CTX["den.ctx"] --- PAR["parametric"] 26 + PAR --- TAKE["take"] 27 + TAKE --- ASP["aspects"] 28 + end 29 + CTX --> A["NixOS"] 30 + CTX --> B["Darwin"] 31 + CTX --> C["Home-Manager"] 32 + CTX --> D["NixVim"] 33 + CTX --> E["Your Nix class"] 34 + ``` 35 + 36 + ## Den the Framework 37 + 38 + On top of the library, Den provides a **framework** for the common case 39 + of managing NixOS/Darwin/Home-Manager configurations: 40 + 41 + - [**`den.hosts`**](/reference/schema/#denhosts) — Host declaration with freeform schema 42 + - [**`den.homes`**](/reference/schema/#denhomes) — Standalone Home-Manager declaration 43 + - [**`den.base`**](/reference/schema/#denbase) — Base modules for entities 44 + - [**`den.default`**](/explanation/context-pipeline/#dendefault-is-an-alias) — Global aspect backbone 45 + - [**`den.provides`**](/reference/batteries/) — Batteries (define-user, unfree, etc.) 46 + - **Built-in `den.ctx` types** — [host, user, hm-host, hm-user, home](/reference/ctx/#built-in-context-types) 47 + 48 + The framework is the **first implementation** using the library, not 49 + the only possible one. 50 + 51 + ## Using Den as a Library 52 + 53 + Context types are independent of NixOS or OS configurations. Den can 54 + configure network topologies, declarative cloud infrastructure, container 55 + orchestration — anything describable as data transformations over 56 + Nix-configurable systems. 57 + 58 + Here is a deployment pipeline example: 59 + 60 + ```nix 61 + den.ctx.deploy.conf = { target }: 62 + den.aspects.${target.name}; 63 + 64 + den.ctx.deploy.into.service = { target }: 65 + map (s: { service = s; target = target; }) 66 + target.services; 67 + 68 + den.ctx.service.conf = { service, target }: 69 + { terraform.resource.${service.name} = { ... }; }; 70 + ``` 71 + 72 + This creates a deployment pipeline where: 73 + 1. Each deploy target has an aspect 74 + 2. Targets enumerate their services 75 + 3. Each service produces Terraform configurations 76 + 77 + The same `ctxApply` mechanics — owned configs, `conf` lookup, 78 + `into` transformations — drive this pipeline without any OS-specific code. 79 + 80 + You can even design and test custom context flows independently of 81 + building any configuration, using Den's test infrastructure. 82 + 83 + ## The Boundary 84 + 85 + ```mermaid 86 + graph TD 87 + subgraph Library["Den Library (any domain)"] 88 + CTX["den.ctx"] 89 + PAR["den.lib.parametric"] 90 + TAKE["den.lib.take"] 91 + ASP["den.lib.aspects"] 92 + FIND["den.lib.__findFile"] 93 + end 94 + subgraph Framework["Den Framework (OS configs)"] 95 + HOSTS["den.hosts / den.homes"] 96 + BASE["den.base"] 97 + DEF["den.default"] 98 + BAT["den.provides (batteries)"] 99 + BUILTIN["Built-in ctx types"] 100 + end 101 + Framework -->|"uses"| Library 102 + ``` 103 + 104 + | Concern | Library | Framework | 105 + |---------|:-------:|:---------:| 106 + | Context types | ✓ | provides built-in types | 107 + | Parametric dispatch | ✓ | uses for host/user routing | 108 + | Aspect composition | ✓ | adds default + batteries | 109 + | Host/user schema | — | ✓ | 110 + | HM integration | — | ✓ | 111 + | Configuration building | — | ✓ | 112 + 113 + ## No Lock-in 114 + 115 + Because the framework is built on the library: 116 + 117 + - You can use the library without the framework 118 + - You can replace any framework component 119 + - You can mix Den-managed and non-Den configs 120 + - You can extend the framework with custom context types 121 + - You can adopt incrementally — one host at a time 122 + 123 + Den doesn't force a project structure, a dependency manager, or a 124 + build system. It plays well with flakes, flake-parts, npins, or 125 + plain `fetchTarball`.
+133
docs/src/content/docs/explanation/parametric.md
··· 1 + --- 2 + title: Parametric Aspects 3 + description: How parametric functors enable context forwarding and adaptation. 4 + --- 5 + 6 + import { Aside } from '@astrojs/starlight/components'; 7 + 8 + <Aside type="tip">Source: [`nix/lib.nix`](https://github.com/vic/den/blob/main/nix/lib.nix) · [`nix/fn-can-take.nix`](https://github.com/vic/den/blob/main/nix/fn-can-take.nix)</Aside> 9 + 10 + ## What Is a Parametric Aspect? 11 + 12 + A **parametric** aspect uses a `__functor` that forwards its received context 13 + to functions in `.includes`. Den provides several parametric functors in 14 + `den.lib.parametric`. 15 + 16 + ## den.lib.parametric (the default) 17 + 18 + The most common functor. Alias for `parametric.withOwn parametric.atLeast`: 19 + 20 + ```nix 21 + den.aspects.foo = den.lib.parametric { 22 + nixos.networking.hostName = "owned"; # always included 23 + includes = [ 24 + ({ host, ... }: { nixos.time.timeZone = "UTC"; }) 25 + ]; 26 + }; 27 + ``` 28 + 29 + When applied with `{ host = ...; user = ...; }`: 30 + 31 + 1. **Owned** configs (`nixos.networking.hostName`) are included 32 + 2. **Static** includes are included 33 + 3. **Functions** matching `atLeast` the context args are called 34 + 35 + ## parametric.atLeast 36 + 37 + Only dispatches to functions — does **not** include owned configs: 38 + 39 + ```nix 40 + F = parametric.atLeast { includes = [ a b c ]; }; 41 + ``` 42 + 43 + Applied with `{ x = 1; y = 2; }`: 44 + - `{ x, ... }: ...` → called (has at least `x`) 45 + - `{ x, y }: ...` → called (has exactly `x, y`) 46 + - `{ z }: ...` → skipped (needs `z`) 47 + 48 + ## parametric.exactly 49 + 50 + Like `atLeast`, but only calls functions with **exactly** matching args: 51 + 52 + ```nix 53 + F = parametric.exactly { includes = [ a b c ]; }; 54 + ``` 55 + 56 + Applied with `{ x = 1; y = 2; }`: 57 + - `{ x, ... }: ...` → skipped (has `...`) 58 + - `{ x, y }: ...` → called (exact match) 59 + - `{ z }: ...` → skipped 60 + 61 + Use `exactly` to prevent duplicate configs when the same function would 62 + match multiple context stages. 63 + 64 + ## parametric.fixedTo 65 + 66 + Replaces the context entirely: 67 + 68 + ```nix 69 + foo = parametric.fixedTo { planet = "Earth"; } { 70 + includes = [ 71 + ({ planet, ... }: { nixos.setting = planet; }) 72 + ]; 73 + }; 74 + ``` 75 + 76 + No matter what context `foo` receives, its includes always get 77 + `{ planet = "Earth"; }`. 78 + 79 + ## parametric.expands 80 + 81 + Adds attributes to the received context: 82 + 83 + ```nix 84 + foo = parametric.expands { planet = "Earth"; } { 85 + includes = [ 86 + ({ host, planet, ... }: { 87 + nixos.setting = "${host.name}/${planet}"; 88 + }) 89 + ]; 90 + }; 91 + ``` 92 + 93 + Applied with `{ host = ...; }`, the includes receive 94 + `{ host = ...; planet = "Earth"; }`. 95 + 96 + ## parametric.withOwn 97 + 98 + Combinator that adds owned config and static includes on top of any 99 + dispatch functor: 100 + 101 + ```nix 102 + parametric.withOwn parametric.atLeast { 103 + nixos.foo = "owned"; # included always 104 + includes = [ 105 + { nixos.bar = "static"; } # included always 106 + ({ host, ... }: { ... }) # dispatched via atLeast 107 + ]; 108 + } 109 + ``` 110 + 111 + ## Matching Rules Summary 112 + 113 + | Functor | Owned | Statics | Functions | 114 + |---------|:-----:|:-------:|:---------:| 115 + | `parametric` (default) | ✓ | ✓ | atLeast | 116 + | `parametric.atLeast` | ✗ | ✗ | atLeast | 117 + | `parametric.exactly` | ✗ | ✗ | exactly | 118 + | `parametric.withOwn F` | ✓ | ✓ | uses F | 119 + | `parametric.fixedTo ctx` | ✓ | ✓ | fixed ctx | 120 + | `parametric.expands ctx` | ✓ | ✓ | ctx + received | 121 + 122 + ## take.exactly and take.atLeast 123 + 124 + For individual functions (not whole aspects), use [`den.lib.take`](/reference/lib/#denlibatake): 125 + 126 + ```nix 127 + den.default.includes = [ 128 + (den.lib.take.exactly ({ host }: { nixos.x = 1; })) 129 + ]; 130 + ``` 131 + 132 + This prevents the function from matching `{ host, user }` contexts, 133 + avoiding duplicate config values.
+88
docs/src/content/docs/guides/angle-brackets.md
··· 1 + --- 2 + title: Angle Brackets Syntax 3 + description: Opt-in shorthand for resolving deep aspect paths. 4 + --- 5 + 6 + import { Aside } from '@astrojs/starlight/components'; 7 + 8 + <Aside type="tip">Source: [`nix/den-brackets.nix`](https://github.com/vic/den/blob/main/nix/den-brackets.nix)</Aside> 9 + 10 + <Aside type="caution">Angle brackets is an experimental, opt-in feature.</Aside> 11 + 12 + ## What It Does 13 + 14 + Den's `__findFile` resolves angle-bracket expressions to aspect paths: 15 + 16 + | Expression | Resolves to | 17 + |------------|-------------| 18 + | `<den.lib>` | `den.lib` | 19 + | `<den.default>` | `den.default` | 20 + | `<igloo>` | `den.aspects.igloo` | 21 + | `<foo/bar>` | `den.aspects.foo.provides.bar` | 22 + | `<foo/bar/baz>` | `den.aspects.foo.provides.bar.provides.baz` | 23 + | `<ns/tools>` | `den.ful.ns.tools` | 24 + 25 + ## Enable Per-Module 26 + 27 + Bring `__findFile` into scope from module arguments: 28 + 29 + ```nix 30 + { den, __findFile, ... }: { 31 + _module.args.__findFile = den.lib.__findFile; 32 + den.aspects.igloo.includes = [ <den/define-user> ]; 33 + } 34 + ``` 35 + 36 + ## Enable Globally 37 + 38 + Create a module that sets it for all modules: 39 + 40 + ```nix 41 + { den, ... }: { 42 + _module.args.__findFile = den.lib.__findFile; 43 + } 44 + ``` 45 + 46 + Then use it anywhere: 47 + 48 + ```nix 49 + { __findFile, ... }: { 50 + den.default.includes = [ <den/define-user> ]; 51 + den.aspects.igloo.includes = [ <foo/bar/baz> ]; 52 + } 53 + ``` 54 + 55 + ## Enable via Let-Binding 56 + 57 + For a single lexical scope: 58 + 59 + ```nix 60 + { den, ... }: 61 + let 62 + inherit (den.lib) __findFile; 63 + in { 64 + den.aspects.igloo.includes = [ <den/define-user> ]; 65 + } 66 + ``` 67 + 68 + ## Namespace Access 69 + 70 + With a namespace `ns` enabled: 71 + 72 + ```nix 73 + { __findFile, ns, ... }: { 74 + ns.moo.silly = true; 75 + # access: 76 + expr = <ns/moo>; # resolves to den.ful.ns.moo 77 + } 78 + ``` 79 + 80 + ## Deep Nested Provides 81 + 82 + Slashes translate to `.provides.` in the aspect tree: 83 + 84 + ```nix 85 + den.aspects.foo.provides.bar.provides.baz.nixos.programs.fish.enable = true; 86 + den.aspects.igloo.includes = [ <foo/bar/baz> ]; 87 + # igloo gets fish enabled 88 + ```
+125
docs/src/content/docs/guides/batteries.md
··· 1 + --- 2 + title: Use Batteries 3 + description: Opt-in, replaceable aspects for common tasks. 4 + --- 5 + 6 + import { Aside } from '@astrojs/starlight/components'; 7 + 8 + <Aside type="tip">Source: [`modules/aspects/provides/`](https://github.com/vic/den/tree/main/modules/aspects/provides) · Reference: [Batteries](/reference/batteries/)</Aside> 9 + 10 + ## What Are Batteries? 11 + 12 + Batteries are pre-built aspects shipped with Den. They are **opt-in** — you 13 + explicitly include them where needed. They are **replaceable** — you can 14 + write your own alternative. 15 + 16 + Access batteries via `den._.` (shorthand for `den.provides.`). 17 + 18 + ## define-user 19 + 20 + Defines a user at both OS and Home-Manager levels: 21 + 22 + ```nix 23 + den.default.includes = [ den._.define-user ]; 24 + ``` 25 + 26 + Sets `users.users.<name>`, `home.username`, and `home.homeDirectory` 27 + automatically for NixOS, Darwin, and standalone Home-Manager. 28 + 29 + ## primary-user 30 + 31 + Makes a user an administrator: 32 + 33 + ```nix 34 + den.aspects.vic.includes = [ den._.primary-user ]; 35 + ``` 36 + 37 + On NixOS: adds `wheel` and `networkmanager` groups. 38 + On Darwin: sets `system.primaryUser`. 39 + On WSL: sets `wsl.defaultUser` if host has a `wsl` attribute. 40 + 41 + ## user-shell 42 + 43 + Sets a user's default shell at OS and HM levels: 44 + 45 + ```nix 46 + den.aspects.vic.includes = [ (den._.user-shell "fish") ]; 47 + ``` 48 + 49 + Enables the shell program on both NixOS/Darwin and Home-Manager, 50 + and sets it as the user's default shell. 51 + 52 + ## unfree 53 + 54 + Enables unfree packages by name: 55 + 56 + ```nix 57 + den.aspects.my-laptop.includes = [ (den._.unfree [ "discord" "slack" ]) ]; 58 + ``` 59 + 60 + Works for any class — NixOS, Darwin, Home-Manager. 61 + 62 + ## tty-autologin 63 + 64 + Enables automatic tty login for a given username: 65 + 66 + ```nix 67 + den.aspects.my-laptop.includes = [ (den._.tty-autologin "root") ]; 68 + ``` 69 + 70 + ## import-tree 71 + 72 + Recursively imports non-dendritic Nix files by class: 73 + 74 + ```nix 75 + den.ctx.host.includes = [ (den._.import-tree._.host ./hosts) ]; 76 + den.ctx.user.includes = [ (den._.import-tree._.user ./users) ]; 77 + ``` 78 + 79 + Given a directory structure like `./hosts/my-laptop/_nixos/`, it auto-imports 80 + files under the matching class directory. Useful for migration. 81 + 82 + ## inputs' and self' (flake-parts) 83 + 84 + Provide per-system `inputs'` and `self'` to NixOS/HM modules: 85 + 86 + ```nix 87 + den.default.includes = [ den._.inputs' den._.self' ]; 88 + 89 + den.aspects.igloo.nixos = { inputs', ... }: { 90 + environment.systemPackages = [ inputs'.nixpkgs.legacyPackages.hello ]; 91 + }; 92 + ``` 93 + 94 + ## forward 95 + 96 + Create custom Nix classes that forward configs into target submodules: 97 + 98 + ```nix 99 + den.aspects.igloo.includes = [ 100 + ({ class, aspect-chain }: 101 + den._.forward { 102 + each = lib.singleton class; 103 + fromClass = _: "custom"; 104 + intoClass = _: "nixos"; 105 + intoPath = _: [ ]; 106 + fromAspect = _: lib.head aspect-chain; 107 + }) 108 + ]; 109 + ``` 110 + 111 + This is how Home-Manager integration is implemented internally. 112 + 113 + ## Writing Your Own 114 + 115 + Any aspect can serve as a battery. Publish it in a namespace for others: 116 + 117 + ```nix 118 + { den, ... }: { 119 + den.provides.my-battery = den.lib.parametric { 120 + includes = [ 121 + ({ host, ... }: { nixos.my-setting = host.name; }) 122 + ]; 123 + }; 124 + } 125 + ```
+95
docs/src/content/docs/guides/bidirectional.md
··· 1 + --- 2 + title: Bidirectional Dependencies 3 + description: Hosts configure users and users configure hosts — automatically. 4 + --- 5 + 6 + ## Host → User Configuration 7 + 8 + A host aspect's `homeManager` settings apply to **all users** on that host: 9 + 10 + ```nix 11 + den.aspects.igloo.homeManager.programs.direnv.enable = true; 12 + ``` 13 + 14 + If `igloo` has users `tux` and `pingu`, both get direnv enabled. 15 + 16 + This also works with static includes: 17 + 18 + ```nix 19 + den.aspects.igloo.includes = [ 20 + { homeManager.programs.direnv.enable = true; } 21 + ]; 22 + ``` 23 + 24 + And with parametric includes that receive context: 25 + 26 + ```nix 27 + den.aspects.igloo.includes = [ 28 + ({ host, user }: { 29 + homeManager.programs.direnv.enable = true; 30 + }) 31 + ]; 32 + ``` 33 + 34 + ## User → Host Configuration 35 + 36 + A user aspect's `nixos` or `darwin` settings apply to **every host** with that user: 37 + 38 + ```nix 39 + den.aspects.tux.nixos.programs.fish.enable = true; 40 + ``` 41 + 42 + If `tux` is on both `igloo` and `iceberg`, both hosts get fish enabled. 43 + 44 + User includes work the same way: 45 + 46 + ```nix 47 + den.aspects.tux.includes = [ 48 + ({ host, ... }: { 49 + nixos.users.users.tux.description = "Tux on ${host.name}"; 50 + }) 51 + ]; 52 + ``` 53 + 54 + ## Context-Conditional Bidirectional 55 + 56 + Combine host and user context for precise control: 57 + 58 + ```nix 59 + let 60 + git-on-linux = { user, host, ... }: 61 + if !lib.hasSuffix "darwin" host.system 62 + then { homeManager.programs.git.enable = true; } 63 + else { }; 64 + in { 65 + den.aspects.tux.includes = [ git-on-linux ]; 66 + } 67 + ``` 68 + 69 + User `tux` gets git only on Linux hosts, not on Darwin. 70 + 71 + ## How It Works 72 + 73 + ```mermaid 74 + graph TD 75 + HA["den.aspects.igloo (host)"] -->|"homeManager class"| U1["tux Home-Manager"] 76 + HA -->|"homeManager class"| U2["pingu Home-Manager"] 77 + UA["den.aspects.tux (user)"] -->|"nixos class"| H1["igloo NixOS"] 78 + UA -->|"nixos class"| H2["iceberg NixOS"] 79 + ``` 80 + 81 + Den’s [context system](/explanation/context-system/) handles the routing: 82 + - Host aspect configs flow to all users on that host 83 + - User aspect configs flow to all hosts with that user 84 + - Context functions get called with the specific `{ host, user }` pair 85 + 86 + ## The `den.default` Backbone 87 + 88 + Settings in [`den.default`](/explanation/context-pipeline/#dendefault-is-an-alias) apply to **everything** — all hosts and all users: 89 + 90 + ```nix 91 + den.default.homeManager.home.stateVersion = "25.11"; 92 + den.default.includes = [ 93 + ({ host, ... }: { ${host.class}.networking.hostName = host.name; }) 94 + ]; 95 + ```
+97
docs/src/content/docs/guides/custom-classes.md
··· 1 + --- 2 + title: Custom Nix Classes 3 + description: Create new Nix configuration classes with den._.forward. 4 + --- 5 + 6 + import { Aside } from '@astrojs/starlight/components'; 7 + 8 + <Aside type="tip">Source: [`modules/aspects/provides/forward.nix`](https://github.com/vic/den/blob/main/modules/aspects/provides/forward.nix) · [CI tests](https://github.com/vic/den/blob/main/templates/ci/modules/forward.nix)</Aside> 9 + 10 + ## What Are Custom Classes? 11 + 12 + Den natively supports `nixos`, `darwin`, and `homeManager` classes. But you 13 + can create your own classes that forward their settings into any target 14 + submodule. This is exactly how Home-Manager integration works internally. 15 + 16 + ## The forward Battery 17 + 18 + `den._.forward` creates an aspect that takes configs from a source class 19 + and inserts them into a target class at a specified path. 20 + 21 + ## Example: Custom Class to NixOS 22 + 23 + Forward a `custom` class into NixOS top-level: 24 + 25 + ```nix 26 + { den, lib, ... }: 27 + let 28 + forwarded = { class, aspect-chain }: 29 + den._.forward { 30 + each = lib.singleton class; 31 + fromClass = _: "custom"; 32 + intoClass = _: "nixos"; 33 + intoPath = _: [ ]; 34 + fromAspect = _: lib.head aspect-chain; 35 + }; 36 + in { 37 + den.aspects.igloo = { 38 + includes = [ forwarded ]; 39 + custom.networking.hostName = "from-custom-class"; 40 + }; 41 + } 42 + ``` 43 + 44 + ## Example: Forward into a Subpath 45 + 46 + Insert configs into a nested submodule: 47 + 48 + ```nix 49 + den.aspects.igloo = { 50 + includes = [ forwarded ]; 51 + nixos.imports = [ 52 + { options.fwd-box = lib.mkOption { 53 + type = lib.types.submoduleWith { modules = [ myModule ]; }; 54 + }; } 55 + ]; 56 + src.items = [ "from-src-class" ]; 57 + }; 58 + ``` 59 + 60 + With `intoPath = _: [ "fwd-box" ]`, the `src` class configs merge into 61 + `nixos.fwd-box`. 62 + 63 + ## How Home-Manager Uses Forward 64 + 65 + Den's Home-Manager integration is built on `forward`: 66 + 67 + ```nix 68 + den._.forward { 69 + each = lib.singleton true; 70 + fromClass = _: "homeManager"; 71 + intoClass = _: host.class; 72 + intoPath = _: [ "home-manager" "users" user.userName ]; 73 + fromAspect = _: userAspect; 74 + } 75 + ``` 76 + 77 + This takes all `homeManager` class configs from user aspects and inserts them 78 + into `home-manager.users.<name>` on the host's OS configuration. 79 + 80 + ## Use Cases 81 + 82 + - **User environments**: Forward a `user` class into `users.users.<name>` 83 + - **Containerization**: Forward a `container` class into systemd-nspawn configs 84 + - **VM configs**: Forward a `vm` class into microvm or QEMU settings 85 + - **Custom tools**: Forward into any Nix-configurable system (NixVim, etc.) 86 + 87 + ## Creating Your Own 88 + 89 + The `forward` function parameters: 90 + 91 + | Parameter | Description | 92 + |-----------|-------------| 93 + | `each` | List of items to iterate over | 94 + | `fromClass` | Source class name (string) | 95 + | `intoClass` | Target class name (string) | 96 + | `intoPath` | Attribute path in target (list of strings) | 97 + | `fromAspect` | Source aspect to read from |
+103
docs/src/content/docs/guides/debug.md
··· 1 + --- 2 + title: Debug Configurations 3 + description: Tools and techniques for debugging Den configurations. 4 + --- 5 + 6 + ## builtins.trace 7 + 8 + Print values during evaluation: 9 + 10 + ```nix 11 + den.aspects.foo = { user, ... }@context: 12 + (builtins.trace context { 13 + nixos = { }; 14 + }); 15 + ``` 16 + 17 + ## builtins.break 18 + 19 + Drop into a REPL at any evaluation point: 20 + 21 + ```nix 22 + den.aspects.foo = { user, ... }@context: 23 + (builtins.break context { 24 + nixos = { }; 25 + }); 26 + ``` 27 + 28 + ## Trace Context Keys 29 + 30 + See which contexts are being applied: 31 + 32 + ```nix 33 + den.default.includes = [ 34 + (context: builtins.trace (builtins.attrNames context) { }) 35 + ]; 36 + ``` 37 + 38 + ## REPL Inspection 39 + 40 + Load your flake and explore interactively: 41 + 42 + ```console 43 + $ nix repl 44 + nix-repl> :lf . 45 + nix-repl> nixosConfigurations.igloo.config.networking.hostName 46 + "igloo" 47 + ``` 48 + 49 + ## Expose den for Inspection 50 + 51 + Temporarily expose the `den` attrset as a flake output: 52 + 53 + ```nix 54 + { den, ... }: { 55 + flake.den = den; # remove when done 56 + } 57 + ``` 58 + 59 + Then in REPL: 60 + 61 + ```console 62 + nix-repl> :lf . 63 + nix-repl> den.aspects.igloo 64 + nix-repl> den.hosts.x86_64-linux.igloo 65 + ``` 66 + 67 + ## Manually Resolve an Aspect 68 + 69 + Test how an aspect resolves for a specific class: 70 + 71 + ```console 72 + nix-repl> module = den.aspects.foo.resolve { class = "nixos"; aspect-chain = []; } 73 + nix-repl> config = (lib.evalModules { modules = [ module ]; }).config 74 + ``` 75 + 76 + For parametric aspects, apply context first: 77 + 78 + ```console 79 + nix-repl> aspect = den.aspects.foo { host = den.hosts.x86_64-linux.igloo; } 80 + nix-repl> module = aspect.resolve { class = "nixos"; aspect-chain = []; } 81 + ``` 82 + 83 + ## Inspect a Host's Main Module 84 + 85 + ```console 86 + nix-repl> module = den.hosts.x86_64-linux.igloo.mainModule 87 + nix-repl> config = (lib.nixosSystem { modules = [ module ]; }).config 88 + ``` 89 + 90 + ## Common Issues 91 + 92 + **Duplicate values in lists**: Your function matches too many contexts. 93 + Use `den.lib.take.exactly` to restrict matching: 94 + 95 + ```nix 96 + den.lib.take.exactly ({ host }: { nixos.x = 1; }) 97 + ``` 98 + 99 + **Missing attribute**: The context doesn't have the expected parameter. 100 + Trace context keys to see what's available. 101 + 102 + **Infinite recursion**: Aspects including each other in a cycle. 103 + Check your `includes` chains for circular dependencies.
+124
docs/src/content/docs/guides/declare-hosts.md
··· 1 + --- 2 + title: Declare Hosts & Users 3 + description: Define your infrastructure entities with Den's freeform schema. 4 + --- 5 + 6 + import { Aside } from '@astrojs/starlight/components'; 7 + 8 + <Aside type="tip">Source: [`modules/_types.nix`](https://github.com/vic/den/blob/main/modules/_types.nix) · Reference: [Entity Schema](/reference/schema/)</Aside> 9 + 10 + ## Hosts and Users 11 + 12 + Declare hosts with a single line per machine: 13 + 14 + ```nix 15 + den.hosts.x86_64-linux.my-laptop.users.vic = { }; 16 + den.hosts.aarch64-darwin.macbook.users.vic = { }; 17 + ``` 18 + 19 + This creates NixOS/Darwin configurations with users, ready for: 20 + 21 + ```console 22 + nixos-rebuild switch --flake .#my-laptop 23 + darwin-rebuild switch --flake .#macbook 24 + ``` 25 + 26 + ## Customize Host Attributes 27 + 28 + Expand the attribute set for full control: 29 + 30 + ```nix 31 + den.hosts.x86_64-linux.my-laptop = { 32 + hostName = "yavanna"; # default: my-laptop 33 + class = "nixos"; # default: guessed from platform 34 + aspect = "workstation"; # default: my-laptop 35 + users.vic = { 36 + userName = "vborja"; # default: vic 37 + aspect = "oeiuwq"; # default: vic 38 + class = "homeManager"; # default: homeManager 39 + }; 40 + }; 41 + ``` 42 + 43 + ## Standalone Home-Manager 44 + 45 + For Home-Manager without a host OS: 46 + 47 + ```nix 48 + den.homes.aarch64-darwin.vic = { }; 49 + ``` 50 + 51 + Build with: 52 + 53 + ```console 54 + home-manager switch --flake .#vic 55 + ``` 56 + 57 + ## Multiple Hosts, Shared Users 58 + 59 + The same user aspect applies to every host it appears on: 60 + 61 + ```nix 62 + den.hosts.x86_64-linux.desktop.users.vic = { }; 63 + den.hosts.x86_64-linux.server.users.vic = { }; 64 + den.hosts.aarch64-darwin.mac.users.vic = { }; 65 + ``` 66 + 67 + All three machines share `den.aspects.vic` configurations. 68 + 69 + ## Freeform Attributes 70 + 71 + Hosts and users accept arbitrary attributes. Use them for metadata 72 + that aspects can inspect: 73 + 74 + ```nix 75 + den.hosts.x86_64-linux.my-laptop = { 76 + isWarm = true; # custom attribute 77 + location = "home"; # custom attribute 78 + users.vic = { }; 79 + }; 80 + ``` 81 + 82 + Then in an aspect: `{ host, ... }: if host.isWarm then ...` 83 + 84 + ## Base Modules 85 + 86 + Add type-checked options to all hosts, users, or homes: 87 + 88 + ```nix 89 + den.base.host = { host, lib, ... }: { 90 + options.vpn-alias = lib.mkOption { default = host.name; }; 91 + }; 92 + 93 + den.base.user = { user, lib, ... }: { 94 + options.main-group = lib.mkOption { default = user.name; }; 95 + }; 96 + 97 + den.base.conf = { lib, ... }: { 98 + options.org = lib.mkOption { default = "acme"; }; 99 + }; 100 + ``` 101 + 102 + `den.base.conf` applies to hosts, users, **and** homes. 103 + 104 + ## Custom Instantiation 105 + 106 + Override how configurations are built: 107 + 108 + ```nix 109 + den.hosts.x86_64-linux.wsl-box = { 110 + class = "nixos"; 111 + instantiate = inputs.nixos-wsl.lib.nixosSystem; 112 + intoAttr = "wslConfigurations"; 113 + users.vic = { }; 114 + }; 115 + ``` 116 + 117 + Different `nixpkgs` channels per host: 118 + 119 + ```nix 120 + den.hosts.x86_64-linux.stable-server = { 121 + instantiate = inputs.nixpkgs-stable.lib.nixosSystem; 122 + users.admin = { }; 123 + }; 124 + ```
+116
docs/src/content/docs/guides/home-manager.md
··· 1 + --- 2 + title: Home-Manager Integration 3 + description: Integrate Home-Manager into NixOS/Darwin hosts or use standalone. 4 + --- 5 + 6 + import { Aside } from '@astrojs/starlight/components'; 7 + 8 + <Aside type="tip">Source: [`hm-os.nix`](https://github.com/vic/den/blob/main/modules/aspects/provides/home-manager/hm-os.nix) · [`hm-integration.nix`](https://github.com/vic/den/blob/main/modules/aspects/provides/home-manager/hm-integration.nix)</Aside> 9 + 10 + ## Automatic HM Detection 11 + 12 + Den automatically detects hosts that need Home-Manager. When a host has 13 + users with `class = "homeManager"` (the default), Den: 14 + 15 + 1. Imports the Home-Manager NixOS/Darwin module 16 + 2. Creates a `homeManager` class for each user 17 + 3. Forwards `homeManager` configs into `home-manager.users.<name>` 18 + 19 + No explicit opt-in needed — just declare users. 20 + 21 + ```mermaid 22 + graph LR 23 + Host["{host}"] -->|"hm-detect"| Check{"class ∈ nixos,darwin?<br/>HM users exist?<br/>HM module available?"} 24 + Check -->|"yes"| HM["ctx.hm-host<br/>imports HM module"] 25 + HM -->|"per user"| FW["forward homeManager<br/>→ home-manager.users.‹name›"] 26 + Check -->|"no"| Skip["HM pipeline skipped"] 27 + ``` 28 + 29 + ## Host-Managed Users 30 + 31 + ```nix 32 + den.hosts.x86_64-linux.igloo.users.tux = { }; 33 + den.default.homeManager.home.stateVersion = "25.11"; 34 + 35 + den.aspects.tux.homeManager.programs.vim.enable = true; 36 + ``` 37 + 38 + The vim config is forwarded into `igloo.home-manager.users.tux`. 39 + 40 + ## Standalone Home-Manager 41 + 42 + For Home-Manager without an OS host: 43 + 44 + ```nix 45 + den.homes.aarch64-darwin.vic = { }; 46 + den.default.homeManager.home.stateVersion = "25.11"; 47 + den.aspects.vic.homeManager.programs.fish.enable = true; 48 + ``` 49 + 50 + Build with `home-manager switch --flake .#vic`. 51 + 52 + ## The define-user Battery 53 + 54 + Use `den._.define-user` to automatically set username and home directory: 55 + 56 + ```nix 57 + den.default.includes = [ den._.define-user ]; 58 + ``` 59 + 60 + This sets `home.username`, `home.homeDirectory`, and 61 + `users.users.<name>` on both NixOS and Darwin. 62 + 63 + ## useGlobalPkgs 64 + 65 + Configure Home-Manager to use the host's nixpkgs: 66 + 67 + ```nix 68 + den.ctx.hm-host.nixos.home-manager.useGlobalPkgs = true; 69 + ``` 70 + 71 + This only activates for hosts that actually have Home-Manager users. 72 + Hosts without users are unaffected. 73 + 74 + ## Custom HM Module 75 + 76 + Override the Home-Manager module source: 77 + 78 + ```nix 79 + den.hosts.x86_64-linux.igloo = { 80 + hm-module = inputs.home-manager-unstable.nixosModules.home-manager; 81 + users.tux = { }; 82 + }; 83 + ``` 84 + 85 + ## Standalone with osConfig 86 + 87 + Access NixOS config from standalone Home-Manager: 88 + 89 + ```nix 90 + den.homes.x86_64-linux.pingu = { 91 + instantiate = { pkgs, modules }: 92 + inputs.home-manager.lib.homeManagerConfiguration { 93 + inherit pkgs modules; 94 + extraSpecialArgs.osConfig = 95 + config.flake.nixosConfigurations.igloo.config; 96 + }; 97 + }; 98 + 99 + den.aspects.pingu.homeManager = { osConfig, ... }: { 100 + programs.emacs.enable = osConfig.programs.vim.enable; 101 + }; 102 + ``` 103 + 104 + ## Context Hooks 105 + 106 + Use `den.ctx.hm-host` to configure things only when HM is active: 107 + 108 + ```nix 109 + den.ctx.hm-host.nixos.home-manager.useGlobalPkgs = true; 110 + den.ctx.hm-host.includes = [ 111 + { nixos.home-manager.backupFileExtension = "bak"; } 112 + ]; 113 + ``` 114 + 115 + These only apply to hosts that have Home-Manager users with 116 + a supported OS (NixOS or Darwin).
+101
docs/src/content/docs/guides/migrate.md
··· 1 + --- 2 + title: Migrate to Den 3 + description: Incrementally adopt Den in existing Nix configurations. 4 + --- 5 + 6 + ## Start Small 7 + 8 + Den can be adopted incrementally. You don't need to rewrite your entire 9 + configuration — start by adding one Den-managed host alongside your 10 + existing setup. 11 + 12 + ## From Flake-Parts Dendritic 13 + 14 + If you're already using `flake.modules`, migration is direct: 15 + 16 + ```nix 17 + # Before (flake-parts dendritic) 18 + flake.modules.nixos.desktop = { ... }; 19 + flake.modules.homeManager.games = { ... }; 20 + 21 + # After (Den) 22 + den.aspects.desktop.nixos = { ... }; 23 + den.aspects.games.homeManager = { ... }; 24 + ``` 25 + 26 + ## Import Existing Modules 27 + 28 + You don't need to convert all modules. Import them directly: 29 + 30 + ```nix 31 + { inputs, ... }: { 32 + den.aspects.desktop.nixos.imports = [ 33 + inputs.disko.nixosModules.disko 34 + inputs.self.modules.nixos.desktop # existing module 35 + ]; 36 + } 37 + ``` 38 + 39 + ## Mix Den with Existing nixosSystem 40 + 41 + Use `mainModule` to integrate Den into existing configurations: 42 + 43 + ```nix 44 + let 45 + denCfg = (lib.evalModules { 46 + modules = [ (import-tree ./modules) ]; 47 + specialArgs = { inherit inputs; }; 48 + }).config; 49 + in 50 + lib.nixosSystem { 51 + modules = [ 52 + ./hardware-configuration.nix # your existing modules 53 + ./networking.nix 54 + denCfg.den.hosts.x86_64-linux.igloo.mainModule # Den modules 55 + ]; 56 + } 57 + ``` 58 + 59 + ## Use import-tree for Gradual Migration 60 + 61 + The [`import-tree`](/reference/batteries/#import-tree) battery auto-imports files by class directory: 62 + 63 + ``` 64 + non-dendritic/ 65 + hosts/ 66 + my-laptop/ 67 + _nixos/ 68 + hardware.nix 69 + networking.nix 70 + _homeManager/ 71 + shell.nix 72 + ``` 73 + 74 + ```nix 75 + den.ctx.host.includes = [ 76 + (den._.import-tree._.host ./non-dendritic/hosts) 77 + ]; 78 + ``` 79 + 80 + Files in `_nixos/` import as NixOS modules, `_homeManager/` as HM modules. 81 + 82 + ## Access Den Configurations Directly 83 + 84 + Den's outputs are standard Nix configurations: 85 + 86 + ```nix 87 + # These are normal nixosSystem / homeManagerConfiguration results 88 + config.flake.nixosConfigurations.igloo 89 + config.flake.homeConfigurations.tux 90 + ``` 91 + 92 + Expose them directly in your flake outputs alongside existing ones. 93 + 94 + ## Recommended Migration Path 95 + 96 + 1. Add Den inputs to your flake 97 + 2. Create a `modules/` directory with `hosts.nix` 98 + 3. Add one host with `den.hosts` 99 + 4. Move one aspect at a time from existing modules 100 + 5. Use `import-tree` for files you haven't converted yet 101 + 6. Gradually expand Den-managed aspects
+104
docs/src/content/docs/guides/namespaces.md
··· 1 + --- 2 + title: Share with Namespaces 3 + description: Share and consume aspect libraries across repositories. 4 + --- 5 + 6 + import { Aside } from '@astrojs/starlight/components'; 7 + 8 + <Aside type="tip">Source: [`nix/namespace.nix`](https://github.com/vic/den/blob/main/nix/namespace.nix)</Aside> 9 + 10 + ## What Are Namespaces? 11 + 12 + Namespaces let you organize aspects into named collections that can be 13 + shared across flakes and consumed by others. 14 + 15 + ## Define a Local Namespace 16 + 17 + ```nix 18 + { inputs, ... }: { 19 + imports = [ (inputs.den.namespace "ns" false) ]; 20 + ns.tools.nixos.programs.vim.enable = true; 21 + } 22 + ``` 23 + 24 + The second argument controls output: 25 + - `false` — local only, not exposed as flake output 26 + - `true` — exposed at `flake.denful.ns` 27 + - A list of sources — merge from external inputs 28 + 29 + ## Consume Remote Namespaces 30 + 31 + Import aspects from another flake's `denful` output: 32 + 33 + ```nix 34 + { inputs, ... }: { 35 + imports = [ 36 + (inputs.den.namespace "provider" [ true inputs.other-flake ]) 37 + ]; 38 + 39 + den.aspects.igloo.includes = [ provider.tools._.editors ]; 40 + } 41 + ``` 42 + 43 + Multiple sources are merged. Local definitions override remote ones. 44 + 45 + ## Nested Provides in Namespaces 46 + 47 + Namespaces support the full aspect tree with `provides`: 48 + 49 + ```nix 50 + ns.root.provides.branch.provides.leaf.nixos.truth = true; 51 + # access via: 52 + ns.root._.branch._.leaf 53 + ``` 54 + 55 + ## Expose as Flake Output 56 + 57 + When the second argument is `true` (or a list containing `true`), 58 + the namespace appears at `config.flake.denful.<name>`: 59 + 60 + ```nix 61 + imports = [ (inputs.den.namespace "ns" true) ]; 62 + ns.foo.nixos.truth = true; 63 + # available at config.flake.denful.ns 64 + ``` 65 + 66 + Other flakes can then consume it: 67 + 68 + ```nix 69 + inputs.your-flake.denful.ns 70 + ``` 71 + 72 + ## Merge Multiple Sources 73 + 74 + Combine local, remote, and output in one namespace: 75 + 76 + ```nix 77 + imports = [ 78 + (inputs.den.namespace "ns" [ 79 + inputs.sourceA 80 + inputs.sourceB 81 + true # also expose as output 82 + ]) 83 + ]; 84 + 85 + ns.gear.nixos.data = [ "local" ]; 86 + # merges with sourceA and sourceB's denful.ns.gear 87 + ``` 88 + 89 + ## Use with Angle Brackets 90 + 91 + When `__findFile` is in scope, namespace aspects are accessible via 92 + angle brackets: 93 + 94 + ```nix 95 + { __findFile, ns, ... }: { 96 + _module.args.__findFile = den.lib.__findFile; 97 + den.aspects.igloo.includes = [ <ns/tools> ]; 98 + } 99 + ``` 100 + 101 + ## Real-World: denful 102 + 103 + [denful](https://github.com/vic/denful) is a community aspect distribution 104 + built on Den namespaces — a lazyvim-like approach to Nix configurations.
+91
docs/src/content/docs/guides/no-flakes.md
··· 1 + --- 2 + title: Use Without Flakes 3 + description: Den works with stable Nix, npins, and without flake-parts. 4 + --- 5 + 6 + ## Den is Flake-Agnostic 7 + 8 + Den does **not** require Nix flakes. It works with: 9 + 10 + - Nix flakes + flake-parts (most common) 11 + - Nix flakes without flake-parts 12 + - No flakes at all (stable Nix + npins or fetchTarball) 13 + 14 + ## Without Flakes 15 + 16 + Use `flake-compat` to evaluate Den from a non-flake setup: 17 + 18 + ```nix 19 + # default.nix 20 + let 21 + flake = import (fetchTarball { 22 + url = "https://github.com/edolstra/flake-compat/archive/...tar.gz"; 23 + }) { src = ./.; }; 24 + in 25 + flake.outputs 26 + ``` 27 + 28 + See the [`noflake` template](https://github.com/vic/den/tree/main/templates/noflake) 29 + for a complete working example with npins. 30 + 31 + ## Without Flake-Parts 32 + 33 + Den provides its own minimal `flake` option when flake-parts is not present. 34 + Simply import `inputs.den.flakeModule`: 35 + 36 + ```nix 37 + let 38 + denCfg = (lib.evalModules { 39 + modules = [ 40 + (import-tree ./modules) 41 + inputs.den.flakeModule 42 + ]; 43 + specialArgs = { inherit inputs; }; 44 + }).config; 45 + in { 46 + nixosConfigurations.igloo = 47 + denCfg.flake.nixosConfigurations.igloo; 48 + } 49 + ``` 50 + 51 + ## With Flake-Parts 52 + 53 + The standard setup — Den integrates seamlessly: 54 + 55 + ```nix 56 + { 57 + outputs = inputs: 58 + inputs.flake-parts.lib.mkFlake { inherit inputs; } 59 + (inputs.import-tree ./modules); 60 + 61 + inputs = { 62 + den.url = "github:vic/den"; 63 + flake-aspects.url = "github:vic/flake-aspects"; 64 + import-tree.url = "github:vic/import-tree"; 65 + nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; 66 + flake-parts.url = "github:hercules-ci/flake-parts"; 67 + }; 68 + } 69 + ``` 70 + 71 + ## The Dendritic Module 72 + 73 + For flake-parts users who want automatic Den + flake-aspects setup: 74 + 75 + ```nix 76 + imports = [ inputs.den.flakeModules.dendritic ]; 77 + ``` 78 + 79 + This auto-configures `flake-file` inputs for `den` and `flake-aspects`. 80 + 81 + ## Minimal Dependencies 82 + 83 + Den's only hard dependency is `flake-aspects`. Everything else is optional: 84 + 85 + | Dependency | Required? | Purpose | 86 + |-----------|-----------|---------| 87 + | `flake-aspects` | **Yes** | [Aspect composition](https://github.com/vic/flake-aspects) | 88 + | `import-tree` | Optional | [Auto-import module directories](https://github.com/vic/import-tree) | 89 + | `flake-parts` | Optional | Flake structuring | 90 + | `nixpkgs` | Optional | Only if building NixOS/HM configs | 91 + | `home-manager` | Optional | Only if using HM integration |
+93
docs/src/content/docs/index.mdx
··· 1 + --- 2 + title: Context-aware Dendritic Nix 3 + description: Context-driven, aspect-oriented, cross-class Nix configurations. 4 + template: splash 5 + hero: 6 + tagline: Context-driven, aspect-oriented, cross-class Nix configurations 7 + image: 8 + html: | 9 + <img width="400" height="400" src="https://github.com/user-attachments/assets/af9c9bca-ab8b-4682-8678-31a70d510bbb" /> 10 + actions: 11 + - text: Get Started 12 + link: /tutorials/getting-started/ 13 + icon: right-arrow 14 + - text: Den Principles 15 + link: /explanation/core-principles 16 + variant: minimal 17 + - text: Why Den? 18 + link: /motivation/ 19 + variant: minimal 20 + - text: Source Code 21 + link: https://github.com/vic/den 22 + icon: github 23 + variant: minimal 24 + --- 25 + 26 + import { Card, CardGrid } from '@astrojs/starlight/components'; 27 + 28 + ## Two Core Principles 29 + 30 + Den builds on [flake-aspects](https://github.com/vic/flake-aspects)' **parametric aspects**, 31 + and provides a declarative **context-pipeline** as cutting-points for these aspects. 32 + 33 + <CardGrid> 34 + <Card title="Context Transformation" icon="random"> 35 + Data flows through a declarative [pipeline](/explanation/context-pipeline/) of 36 + [contexts](/explanation/context-system/). Each stage enriches the context — from 37 + host definitions through user enumeration to domain-specific requirements. 38 + </Card> 39 + <Card title="Context-Aware Aspects" icon="puzzle"> 40 + [Aspects](/explanation/aspects/) are composable bundles of cross-class Nix configs. 41 + They inspect context to produce conditional, [parametric](/explanation/parametric/) 42 + configurations — and are activated by a matching context. 43 + </Card> 44 + </CardGrid> 45 + 46 + ## Den as a Library 47 + 48 + All parts of Den are optional, re-usable and replaceable. Even the default NixOS configuration 49 + pipeline is opt-in, and you can use Den lib to configure anything supporting Nix modules. 50 + 51 + <CardGrid> 52 + <Card title="Any Nix Class" icon="none"> 53 + NixOS, Darwin, Home-Manager, Terraform, NixVim — Den 54 + works with [anything configurable through Nix](/explanation/library-vs-framework/). 55 + </Card> 56 + <Card title="Context Pipeline" icon="right-arrow"> 57 + Define custom [context types](/reference/ctx/) with `den.ctx`. Declarative 58 + [transformations](/explanation/context-pipeline/) propagate data through your config graph. 59 + </Card> 60 + <Card title="No Lock-in" icon="open-book"> 61 + Works [with flakes, without flakes](/guides/no-flakes/), with flake-parts, or 62 + standalone. Den plays well with your existing Nix choices. And integrates with your existing infra. 63 + </Card> 64 + <Card title="Sharable Aspects" icon="star"> 65 + Re-usablity is one of the goals of Den. Allowing people to create truly-generic configuration modules. 66 + [Namespaces](/guides/namespaces/) let you publish and consume aspect libraries 67 + across repositories and flakes. 68 + </Card> 69 + </CardGrid> 70 + 71 + ## Den as a Framework 72 + 73 + Built upon `den.lib`, Den provides ready-made facilities for the common use-case of OS and User configurations. 74 + 75 + <CardGrid> 76 + <Card title="Declare Systems" icon="laptop"> 77 + One-liner [host and user](/guides/declare-hosts/) definitions with 78 + [freeform schemas](/reference/schema/). NixOS, Darwin, Home-Manager — 79 + all from a single source. 80 + </Card> 81 + <Card title="Bidirectional" icon="right-arrow"> 82 + Hosts configure their users. Users contribute to their 83 + hosts. [Aspects flow in both directions](/guides/bidirectional/) automatically. 84 + </Card> 85 + <Card title="Batteries Included" icon="add-document"> 86 + Opt-in [aspects for common tasks](/guides/batteries/): define-user, primary-user, 87 + user-shell, unfree packages, import-tree, and more. 88 + </Card> 89 + <Card title="Community" icon="heart"> 90 + Share configurations through [namespaces](/guides/namespaces/). Real-world setups 91 + and a growing ecosystem at [denful](https://github.com/vic/denful) (wip). 92 + </Card> 93 + </CardGrid>
+95
docs/src/content/docs/motivation.md
··· 1 + --- 2 + title: Why Den? 3 + description: The motivation and fundamental idea behind Den. 4 + --- 5 + 6 + ## Den Origins 7 + 8 + Den started by exploring the re-usability enabled by the [Dendritic Nix](https://dendrix.oeiuwq.com/Dendritic.html) pattern. 9 + 10 + Traditional Nix configurations are powerful but isolated. Even when all nix modules are already functions, it is not common to share configurations outside of what is provided by `NixOS` and projects like `Home Manager` or `Hjem Run`. 11 + 12 + All these different configuration domains have different option sets, they share nothing in common except that they are nix modules. Passing values between different classes of configurations is not intuitive. 13 + 14 + When writing their infra, most people do re-invent the wheel an infinite number of times. And most of this is because configurations are not written with re-usability in mind. The result is you find people copy-pasting from other's repositories, or letting an AI slop-generate whatever it had consumed. 15 + 16 + ## The Fundamental Idea 17 + 18 + Just like any Nix module can already be a function. Den explores the idea of Dendritic aspects being functions. 19 + 20 + ```nix 21 + # a NixOS module is a function. 22 + { pkgs, ... }: { .... }; 23 + 24 + # a Dendritic aspect can be a function. 25 + { host, user }: { 26 + nixos = { pkgs, ... }: { users.users.${user.name}.packages = [ pkgs.hello ] }; 27 + }; 28 + 29 + ``` 30 + 31 + 32 + > Configurations that are **functions of context** become truly re-usable. 33 + > An important point is that `{ host, user }` are NOT module arguments in 34 + > the nix-modules sense. Because they do not depend on config you can use 35 + > them for conditional inclusion of other features. 36 + 37 + Instead of writing a NixOS module tied to one machine, you write an [**aspect**](/explanation/aspects/) — a 38 + function that receives [context](/explanation/context-system/) (which host, which user, which platform) and produces 39 + configurations for any Nix class it needs: 40 + 41 + ```nix 42 + { host, user, ... }: { 43 + nixos.users.users.${user.userName}.description = "${user.userName} on ${host.name}"; 44 + darwin.users.users.${user.userName}.home = "/Users/${user.userName}"; 45 + homeManager.programs.git.userName = user.userName; 46 + } 47 + ``` 48 + 49 + One function. Three classes. Any host. Any user. **Truly parametric.** 50 + 51 + ## Two Core Principles 52 + 53 + ### 1. Context Transformation 54 + 55 + Data flows through a declarative pipeline. You declare the entities (data) that exists in your universe, Den transforms them into progressively richer contexts to which aspects are attached, providing configuration: 56 + 57 + ```mermaid 58 + graph LR 59 + H["den.ctx.host {host}"] --> U["den.ctx.user {host, user} (for each user)"] 60 + U --> HM["aspect provides homeManager/hjeim class"] 61 + H --> OS["aspect provides nixos/darwin class"] 62 + ``` 63 + 64 + Each stage of the pipeline is a [**context type**](/reference/ctx/) defined in `den.ctx`. Context types 65 + declare how to find [aspects](/explanation/aspects/), how to transform into other contexts, and which 66 + [parametric](/explanation/parametric/) includes to activate. 67 + 68 + ### 2. Context-Aware Aspects 69 + 70 + Aspects are composable bundles that inspect their context parameters to decide 71 + what to produce. A function taking `{ host, ... }` only runs when a host context 72 + exists. A function taking `{ host, user, ... }` runs once per user on each host. 73 + 74 + Functions that require parameters not present in the current context are 75 + not included. Den introduces pattern matching on context shape. 76 + 77 + ## Den is Social 78 + 79 + Den is fundamentally born to solve a **social** problem: making Dendritic Nix configurations shareable. 80 + 81 + Den's [**namespaces**](/guides/namespaces/) and [**aspects**](/explanation/aspects/) create a common language for sharing 82 + configurations across repositories, even across flake/non-flake projects, and communities. 83 + 84 + ## Built on Flake-Aspects 85 + 86 + Den is built on [flake-aspects](https://github.com/vic/flake-aspects) — a 87 + dependency-free library for composable, nested, parametric aspect trees. 88 + Den adds the context transformation pipeline and framework integration 89 + on top of this foundation. 90 + 91 + ## What's Next? 92 + 93 + Ready to try it? Head to the [Getting Started](/tutorials/getting-started/) tutorial. 94 + 95 + Want to understand the architecture? Read about the [Core Principles](/explanation/core-principles/).
+127
docs/src/content/docs/reference/aspects.md
··· 1 + --- 2 + title: den.aspects Reference 3 + description: Aspect structure, resolution, and configuration. 4 + --- 5 + 6 + import { Aside } from '@astrojs/starlight/components'; 7 + 8 + <Aside type="tip">Source: [`modules/aspects.nix`](https://github.com/vic/den/blob/main/modules/aspects.nix) · [`modules/aspects/definition.nix`](https://github.com/vic/den/blob/main/modules/aspects/definition.nix) · [`modules/aspects/provides.nix`](https://github.com/vic/den/blob/main/modules/aspects/provides.nix)</Aside> 9 + 10 + ## Aspect Attributes 11 + 12 + Every aspect is an attribute set with these recognized keys: 13 + 14 + | Attribute | Type | Description | 15 + |-----------|------|-------------| 16 + | `nixos` | module | NixOS configuration module | 17 + | `darwin` | module | nix-darwin configuration module | 18 + | `homeManager` | module | Home-Manager configuration module | 19 + | `<class>` | module | Any custom Nix class | 20 + | `includes` | list | Dependencies on other aspects or functions | 21 + | `provides` | attrset | Nested sub-aspects | 22 + | `_` | alias | Shorthand for `provides` | 23 + | `description` | str | Human-readable description | 24 + | `__functor` | function | Context-aware behavior | 25 + 26 + ## Automatic Aspect Creation 27 + 28 + Den creates an aspect for each host, user, and home you declare: 29 + 30 + ```nix 31 + den.hosts.x86_64-linux.igloo.users.tux = { }; 32 + # Creates: den.aspects.igloo and den.aspects.tux 33 + ``` 34 + 35 + Aspects are created with `parametric { <class> = {}; }` functor 36 + matching the entity's class. 37 + 38 + ## Aspect Resolution 39 + 40 + To extract a class module from an aspect: 41 + 42 + ```nix 43 + module = aspect.resolve { class = "nixos"; aspect-chain = []; }; 44 + ``` 45 + 46 + Resolution collects the specified class from the aspect and all 47 + transitive includes into a single merged Nix module. 48 + 49 + ## den.aspects (option) 50 + 51 + ```nix 52 + options.den.aspects = lib.mkOption { 53 + type = aspectsType; 54 + default = { }; 55 + }; 56 + ``` 57 + 58 + Contributions from any module are merged: 59 + 60 + ```nix 61 + # file1.nix 62 + den.aspects.igloo.nixos.networking.hostName = "igloo"; 63 + 64 + # file2.nix 65 + den.aspects.igloo.homeManager.programs.vim.enable = true; 66 + ``` 67 + 68 + ## den.provides (batteries) 69 + 70 + ```nix 71 + options.den.provides = lib.mkOption { 72 + type = lib.types.submodule { 73 + freeformType = lib.types.attrsOf providerType; 74 + }; 75 + }; 76 + ``` 77 + 78 + Access via `den._.name` or `den.provides.name`. 79 + See [Batteries Reference](/reference/batteries/) for all built-in aspects. 80 + 81 + ## den.default 82 + 83 + The global dispatcher aspect: 84 + 85 + ```nix 86 + den.default = den.lib.parametric.atLeast { }; 87 + ``` 88 + 89 + All hosts, users, and homes include `den.default`. Set global 90 + configs and shared [parametric](/explanation/parametric/) includes here. 91 + 92 + Aliased from `den.ctx.default`. 93 + 94 + ## Including Aspects 95 + 96 + ```nix 97 + den.aspects.igloo.includes = [ 98 + # another aspect 99 + den.aspects.gaming 100 + 101 + # nested provides 102 + den.aspects.tools._.editors 103 + 104 + # static config 105 + { homeManager.programs.direnv.enable = true; } 106 + 107 + # context function 108 + ({ host, ... }: { nixos.time.timeZone = "UTC"; }) 109 + 110 + # battery 111 + den._.define-user 112 + 113 + # battery with args 114 + (den._.user-shell "fish") 115 + (den._.unfree [ "discord" ]) 116 + ]; 117 + ``` 118 + 119 + ## Aspect as Module Argument 120 + 121 + `den` is available as a module argument in all Den modules: 122 + 123 + ```nix 124 + { den, ... }: { 125 + den.aspects.foo = den.lib.parametric { ... }; 126 + } 127 + ```
+156
docs/src/content/docs/reference/batteries.md
··· 1 + --- 2 + title: Batteries Reference 3 + description: All built-in opt-in aspects shipped with Den. 4 + --- 5 + 6 + import { Aside } from '@astrojs/starlight/components'; 7 + 8 + <Aside type="tip">Source: [`modules/aspects/provides/`](https://github.com/vic/den/tree/main/modules/aspects/provides)</Aside> 9 + 10 + ## Overview 11 + 12 + Batteries are pre-built aspects at `den.provides` (accessed via `den._.<name>`). 13 + All are opt-in — include them explicitly where needed. 14 + 15 + ## define-user 16 + 17 + Defines a user at OS and Home-Manager levels. 18 + ([source](https://github.com/vic/den/blob/main/modules/aspects/provides/define-user.nix)) 19 + 20 + ```nix 21 + den.default.includes = [ den._.define-user ]; 22 + ``` 23 + 24 + **Sets:** 25 + - `users.users.<name>.{name, home, isNormalUser}` (NixOS) 26 + - `users.users.<name>.{name, home}` (Darwin) 27 + - `home.{username, homeDirectory}` (Home-Manager) 28 + 29 + **Contexts:** `{ host, user }`, `{ home }` 30 + 31 + ## primary-user 32 + 33 + Makes a user an administrator. 34 + ([source](https://github.com/vic/den/blob/main/modules/aspects/provides/primary-user.nix)) 35 + 36 + ```nix 37 + den.aspects.vic.includes = [ den._.primary-user ]; 38 + ``` 39 + 40 + **Sets:** 41 + - NixOS: `users.users.<name>.extraGroups = [ "wheel" "networkmanager" ]` 42 + - Darwin: `system.primaryUser = <name>` 43 + - WSL: `wsl.defaultUser = <name>` (if host has `wsl` attribute) 44 + 45 + **Context:** `{ host, user }` 46 + 47 + ## user-shell 48 + 49 + Sets default shell at OS and HM levels. 50 + ([source](https://github.com/vic/den/blob/main/modules/aspects/provides/user-shell.nix)) 51 + 52 + ```nix 53 + den.aspects.vic.includes = [ (den._.user-shell "fish") ]; 54 + ``` 55 + 56 + **Sets:** 57 + - `programs.<shell>.enable = true` (NixOS/Darwin) 58 + - `users.users.<name>.shell = pkgs.<shell>` (NixOS/Darwin) 59 + - `programs.<shell>.enable = true` (Home-Manager) 60 + 61 + **Contexts:** `{ host, user }`, `{ home }` 62 + 63 + ## unfree 64 + 65 + Enables unfree packages by name. 66 + ([source](https://github.com/vic/den/blob/main/modules/aspects/provides/unfree/unfree-predicate-builder.nix) · [predicate](https://github.com/vic/den/blob/main/modules/aspects/provides/unfree/unfree.nix)) 67 + 68 + ```nix 69 + den.aspects.laptop.includes = [ (den._.unfree [ "discord" ]) ]; 70 + ``` 71 + 72 + **Sets:** `unfree.packages` option + `nixpkgs.config.allowUnfreePredicate` 73 + 74 + **Contexts:** All (host, user, home) — works for any class. 75 + 76 + :::note[useGlobalPkgs interaction] 77 + When Home-Manager's `useGlobalPkgs` is `true`, the unfree module 78 + skips setting `nixpkgs.config` on the HM class to avoid conflicts. 79 + Set unfree packages on the **host** aspect instead. 80 + ::: 81 + 82 + ## tty-autologin 83 + 84 + Automatic tty login. 85 + 86 + ```nix 87 + den.aspects.laptop.includes = [ (den._.tty-autologin "root") ]; 88 + ``` 89 + 90 + **Sets:** `systemd.services."getty@tty1"` with autologin. 91 + 92 + **Class:** NixOS only. 93 + 94 + ## import-tree 95 + 96 + Auto-imports non-dendritic Nix files by class directory. 97 + ([source](https://github.com/vic/den/blob/main/modules/aspects/provides/import-tree.nix)) 98 + 99 + ```nix 100 + den.aspects.laptop.includes = [ (den._.import-tree ./path) ]; 101 + ``` 102 + 103 + Looks for `./path/_nixos/`, `./path/_darwin/`, `./path/_homeManager/`. 104 + 105 + **Helpers:** 106 + 107 + ```nix 108 + den._.import-tree._.host ./hosts # per host: ./hosts/<name>/_<class> 109 + den._.import-tree._.user ./users # per user: ./users/<name>/_<class> 110 + den._.import-tree._.home ./homes # per home: ./homes/<name>/_<class> 111 + ``` 112 + 113 + **Requires:** `inputs.import-tree` 114 + 115 + ## inputs' (flake-parts) 116 + 117 + Provides per-system `inputs'` as a module argument. 118 + 119 + ```nix 120 + den.default.includes = [ den._.inputs' ]; 121 + ``` 122 + 123 + **Requires:** flake-parts with `withSystem`. 124 + 125 + ## self' (flake-parts) 126 + 127 + Provides per-system `self'` as a module argument. 128 + 129 + ```nix 130 + den.default.includes = [ den._.self' ]; 131 + ``` 132 + 133 + **Requires:** flake-parts with `withSystem`. 134 + 135 + ## forward 136 + 137 + Creates custom Nix classes by forwarding configs between classes. 138 + ([source](https://github.com/vic/den/blob/main/modules/aspects/provides/forward.nix) · [usage guide](/guides/custom-classes/)) 139 + 140 + ```nix 141 + den._.forward { 142 + each = lib.singleton class; 143 + fromClass = _: "source"; 144 + intoClass = _: "nixos"; 145 + intoPath = _: [ "target" "path" ]; 146 + fromAspect = _: sourceAspect; 147 + } 148 + ``` 149 + 150 + Returns an aspect. Used internally for Home-Manager integration. 151 + 152 + ## home-manager 153 + 154 + Empty marker aspect. The actual HM integration is handled by 155 + `den.ctx.hm-host` and `den.ctx.hm-user` context types, which are 156 + activated automatically when hosts have HM users.
+180
docs/src/content/docs/reference/ctx.md
··· 1 + --- 2 + title: den.ctx Reference 3 + description: Context type definitions and their built-in implementations. 4 + --- 5 + 6 + import { Aside } from '@astrojs/starlight/components'; 7 + 8 + <Aside type="tip">Source: [`modules/context/types.nix`](https://github.com/vic/den/blob/main/modules/context/types.nix) · [`modules/context/os.nix`](https://github.com/vic/den/blob/main/modules/context/os.nix) · [`modules/aspects/defaults.nix`](https://github.com/vic/den/blob/main/modules/aspects/defaults.nix)</Aside> 9 + 10 + ## Context Type Schema 11 + 12 + Each `den.ctx.<name>` is a submodule with these options: 13 + 14 + | Option | Type | Description | 15 + |--------|------|-------------| 16 + | `desc` | `str` | Human-readable description | 17 + | `conf` | `ctx → aspect` | Locates the aspect for this context | 18 + | `into` | `attrset of (ctx → list)` | Transformations to other contexts | 19 + | `includes` | `list of aspect` | Parametric aspects activated for this context | 20 + 21 + Context types are also functors — callable as functions: 22 + 23 + ```nix 24 + aspect = den.ctx.host { host = den.hosts.x86_64-linux.igloo; }; 25 + ``` 26 + 27 + ## ctxApply (internal) 28 + 29 + When a context type is applied, `ctxApply` executes: 30 + 31 + ```nix 32 + ctxApply = self: ctx: { 33 + includes = lib.flatten [ 34 + (parametric.fixedTo ctx (cleanCtx self)) # owned configs 35 + (self.conf ctx) # located aspect 36 + (mapAttrsToList (name: into: # transformations 37 + map den.ctx.${name} (into ctx) 38 + ) self.into) 39 + ]; 40 + }; 41 + ``` 42 + 43 + ## Transformation Types 44 + 45 + All `into` transformations have the type `source → [ target ]`: 46 + 47 + - **Fan-out**: `{ host }: map (u: { inherit host user; }) users` — one host produces N contexts 48 + - **Conditional**: `{ host }: lib.optional (test host) { inherit host; }` — zero or one 49 + - **Pass-through**: `lib.singleton` — forward the same data as-is 50 + 51 + An empty list means the target context is not created. This enables 52 + conditional activation like HM detection without any explicit `if` logic 53 + in the pipeline. 54 + 55 + ## Contexts as Cutting-Points 56 + 57 + Context types have their own owned configs and `includes`, making them 58 + aspect-like cutting-points in the pipeline: 59 + 60 + ```nix 61 + den.ctx.hm-host.nixos.home-manager.useGlobalPkgs = true; 62 + den.ctx.hm-host.includes = [ 63 + ({ host, ... }: { nixos.home-manager.backupFileExtension = "bak"; }) 64 + ]; 65 + ``` 66 + 67 + These only activate for validated HM hosts — more precise than 68 + `den.default.includes` which runs at every pipeline stage. 69 + 70 + ## Extending Context Flow 71 + 72 + Add transformations to existing context types from any module: 73 + 74 + ```nix 75 + den.ctx.hm-host.into.foo = { host }: [ { foo = host.name; } ]; 76 + den.ctx.foo.conf = { foo }: { funny.names = [ foo ]; }; 77 + ``` 78 + 79 + The module system merges these definitions. You can also override a 80 + host's `mainModule` to use a completely custom context flow. 81 + 82 + ## Built-in Context Types 83 + 84 + ### den.ctx.host 85 + 86 + | Field | Value | 87 + |-------|-------| 88 + | `desc` | OS | 89 + | `conf` | `{ host }:` fixedTo host aspect | 90 + | `into.default` | `lib.singleton` (pass-through) | 91 + | `into.user` | Enumerate `host.users` | 92 + | `into.hm-host` | Detect HM support (from `hm-detect.nix`) | 93 + 94 + ### den.ctx.user 95 + 96 + | Field | Value | 97 + |-------|-------| 98 + | `desc` | OS user | 99 + | `conf` | `{ host, user }:` includes user + host aspects | 100 + | `into.default` | `lib.singleton` (pass-through) | 101 + 102 + ### den.ctx.default 103 + 104 + | Field | Value | 105 + |-------|-------| 106 + | `conf` | `_: { }` (empty — just a dispatcher) | 107 + 108 + Aliased as `den.default` via `lib.mkAliasOptionModule`. 109 + Writing `den.default.foo` is identical to `den.ctx.default.foo`. 110 + 111 + Every context type transforms into `default`, so `den.default.includes` 112 + functions run at every pipeline stage. Use `take.exactly` to restrict 113 + matching if you see duplicate values. 114 + 115 + ### den.ctx.home 116 + 117 + | Field | Value | 118 + |-------|-------| 119 + | `desc` | Standalone Home-Manager config | 120 + | `conf` | `{ home }:` fixedTo home aspect | 121 + | `into.default` | `lib.singleton` | 122 + 123 + ### den.ctx.hm-host 124 + 125 + | Field | Value | 126 + |-------|-------| 127 + | `desc` | Host with HM-supported OS and HM users | 128 + | `conf` | `{ host }:` imports HM NixOS/Darwin module | 129 + | `into.hm-user` | Enumerate HM-class users | 130 + 131 + **Detection criteria** (all must be true): 132 + 1. Host class is `nixos` or `darwin` 133 + 2. At least one user has `class = "homeManager"` 134 + 3. `inputs.home-manager` exists, or host has a custom `hm-module` attribute 135 + 136 + If detection fails, the HM pipeline is skipped entirely. 137 + 138 + ### den.ctx.hm-user 139 + 140 + | Field | Value | 141 + |-------|-------| 142 + | `desc` | Internal — forwards HM class to host | 143 + | `conf` | `{ host, user }:` forward homeManager into host | 144 + 145 + ### den.ctx.hm-internal-user (internal) 146 + 147 + An internal context type used by `hm-user`. It combines: 148 + - The user context (`den.ctx.user { host, user }`) 149 + - Owned configs from the host aspect 150 + - Static includes from the host aspect 151 + - Parametric includes from the host aspect matching `{ host, user }` 152 + 153 + This ensures that when the `homeManager` class is forwarded into 154 + `home-manager.users.<name>`, it receives contributions from both 155 + the user's aspect and the host's aspect. 156 + 157 + ## Defining Custom Context Types 158 + 159 + Context types are independent of NixOS. Use them for any domain: 160 + 161 + ```nix 162 + den.ctx.myctx = { 163 + desc = "{x, y} context"; 164 + conf = { x, y }: { funny.names = [ x y ]; }; 165 + includes = [ 166 + ({ x, ... }: { funny.names = [ "include-${x}" ]; }) 167 + ]; 168 + into = { 169 + other = { x, y }: [{ z = x + y; }]; 170 + }; 171 + }; 172 + ``` 173 + 174 + Owned attributes (anything not `desc`, `conf`, `into`, `includes`) 175 + are included when the context is applied. 176 + 177 + Custom context flows can be designed and tested in isolation — Den's 178 + CI tests use a `funny.names` class that has nothing to do with NixOS 179 + to verify the context mechanics independently.See the [CI test suite](https://github.com/vic/den/tree/main/templates/ci/modules) 180 + for examples.
+146
docs/src/content/docs/reference/lib.md
··· 1 + --- 2 + title: den.lib Reference 3 + description: Library functions for parametric dispatch and context handling. 4 + --- 5 + 6 + import { Aside } from '@astrojs/starlight/components'; 7 + 8 + <Aside type="tip">Source: [`nix/lib.nix`](https://github.com/vic/den/blob/main/nix/lib.nix) · [`nix/fn-can-take.nix`](https://github.com/vic/den/blob/main/nix/fn-can-take.nix) · [`nix/den-brackets.nix`](https://github.com/vic/den/blob/main/nix/den-brackets.nix)</Aside> 9 + 10 + ## den.lib.parametric 11 + 12 + Creates a parametric aspect. Alias for `parametric.withOwn parametric.atLeast`. 13 + 14 + ```nix 15 + den.lib.parametric { nixos.x = 1; includes = [ f ]; } 16 + ``` 17 + 18 + Includes owned configs, statics, and dispatches to functions via `atLeast`. 19 + 20 + ### parametric.atLeast 21 + 22 + Dispatches **only** to functions whose required args are a subset of context: 23 + 24 + ```nix 25 + F = parametric.atLeast { includes = [ a b ]; }; 26 + ``` 27 + 28 + ### parametric.exactly 29 + 30 + Dispatches **only** to functions whose args match context exactly: 31 + 32 + ```nix 33 + F = parametric.exactly { includes = [ a b ]; }; 34 + ``` 35 + 36 + ### parametric.fixedTo 37 + 38 + Replaces context with a fixed attribute set: 39 + 40 + ```nix 41 + F = parametric.fixedTo { x = 1; } aspect; 42 + ``` 43 + 44 + ### parametric.expands 45 + 46 + Merges extra attributes into received context: 47 + 48 + ```nix 49 + F = parametric.expands { extra = 1; } aspect; 50 + ``` 51 + 52 + ### parametric.withOwn 53 + 54 + Combinator: adds owned + statics on top of a dispatch functor: 55 + 56 + ```nix 57 + F = parametric.withOwn parametric.exactly aspect; 58 + ``` 59 + 60 + ## den.lib.take 61 + 62 + Individual function matching: 63 + 64 + ### take.atLeast 65 + 66 + ```nix 67 + den.lib.take.atLeast ({ host, ... }: { nixos.x = 1; }) 68 + ``` 69 + 70 + Wraps function to only be called when context has at least the required args. 71 + 72 + ### take.exactly 73 + 74 + ```nix 75 + den.lib.take.exactly ({ host }: { nixos.x = 1; }) 76 + ``` 77 + 78 + Only called when context has exactly these args, no more. 79 + 80 + ### take.unused 81 + 82 + ```nix 83 + den.lib.take.unused ignored_value result 84 + ``` 85 + 86 + Returns `result`, ignoring the first argument. Used internally. 87 + 88 + ## den.lib.canTake 89 + 90 + Function signature introspection: 91 + 92 + ```nix 93 + den.lib.canTake { x = 1; } someFunction 94 + # => true if someFunction can take at least { x } 95 + 96 + den.lib.canTake.atLeast { x = 1; } someFunction 97 + den.lib.canTake.exactly { x = 1; y = 2; } someFunction 98 + ``` 99 + 100 + ## den.lib.aspects 101 + 102 + Re-export of `flake-aspects` library. Provides: 103 + - `aspects.types.aspectsType` — module type for aspect trees 104 + - `aspects.types.providerType` — type for aspect providers 105 + - `aspects.forward` — class forwarding implementation 106 + 107 + ## den.lib.isFn 108 + 109 + Checks if a value is callable (function or attrset with `__functor`): 110 + 111 + ```nix 112 + den.lib.isFn someValue # => bool 113 + ``` 114 + 115 + ## den.lib.owned 116 + 117 + Extracts only owned configs from an aspect (removes `includes`, `__functor`): 118 + 119 + ```nix 120 + den.lib.owned someAspect # => { nixos = ...; darwin = ...; } 121 + ``` 122 + 123 + ## den.lib.statics 124 + 125 + Creates a functor that only resolves static includes from an aspect: 126 + 127 + ```nix 128 + den.lib.statics someAspect { class = "nixos"; aspect-chain = []; } 129 + ``` 130 + 131 + ## den.lib.isStatic 132 + 133 + Checks if a function requires only `{ class, aspect-chain }`: 134 + 135 + ```nix 136 + den.lib.isStatic someFunction # => bool 137 + ``` 138 + 139 + ## den.lib.__findFile 140 + 141 + Angle-bracket resolver. Translates `<path>` expressions to aspect lookups: 142 + 143 + ```nix 144 + _module.args.__findFile = den.lib.__findFile; 145 + # then: <foo/bar> => den.aspects.foo.provides.bar 146 + ```
+109
docs/src/content/docs/reference/output.md
··· 1 + --- 2 + title: Configuration Output 3 + description: How Den builds and outputs final NixOS, Darwin, and Home-Manager configurations. 4 + --- 5 + 6 + import { Aside } from '@astrojs/starlight/components'; 7 + 8 + <Aside type="tip">Source: [`modules/config.nix`](https://github.com/vic/den/blob/main/modules/config.nix) · [`modules/output.nix`](https://github.com/vic/den/blob/main/modules/output.nix)</Aside> 9 + 10 + ## Overview 11 + 12 + Den transforms `den.hosts` and `den.homes` declarations into standard Nix 13 + configurations placed on `flake.nixosConfigurations`, `flake.darwinConfigurations`, 14 + and `flake.homeConfigurations`. 15 + 16 + ```mermaid 17 + graph LR 18 + H["den.hosts"] -->|"osConfiguration"| NC["flake.nixosConfigurations"] 19 + H -->|"osConfiguration"| DC["flake.darwinConfigurations"] 20 + HM["den.homes"] -->|"homeConfiguration"| HC["flake.homeConfigurations"] 21 + ``` 22 + 23 + ## The Build Process 24 + 25 + For each entry in `den.hosts` and `den.homes`, Den: 26 + 27 + 1. **Resolves the main module** — applies the context pipeline to produce a 28 + single Nix module containing all class-specific configurations 29 + 2. **Calls the instantiate function** — passes the module to the platform builder 30 + 3. **Places the result** — puts it at `flake.<intoAttr>.<name>` 31 + 32 + ## OS Configurations 33 + 34 + Each host in `den.hosts.<system>.<name>` builds via: 35 + 36 + ```nix 37 + host.instantiate { 38 + modules = [ 39 + host.mainModule 40 + { nixpkgs.hostPlatform = lib.mkDefault host.system; } 41 + ]; 42 + } 43 + ``` 44 + 45 + The `mainModule` is the result of applying `den.ctx.host { host }` and 46 + resolving the aspect tree for the host's class. 47 + 48 + ## Home Configurations 49 + 50 + Each home in `den.homes.<system>.<name>` builds via: 51 + 52 + ```nix 53 + home.instantiate { 54 + pkgs = home.pkgs; 55 + modules = [ home.mainModule ]; 56 + } 57 + ``` 58 + 59 + Where `home.pkgs` defaults to `inputs.nixpkgs.legacyPackages.<system>`. 60 + 61 + ## Output Placement 62 + 63 + Results are folded into `flake` by `intoAttr`: 64 + 65 + | Class | Default `intoAttr` | 66 + |-------|-------------------| 67 + | `nixos` | `nixosConfigurations` | 68 + | `darwin` | `darwinConfigurations` | 69 + | `systemManager` | `systemConfigs` | 70 + | `homeManager` | `homeConfigurations` | 71 + 72 + Override `intoAttr` to place configs elsewhere: 73 + 74 + ```nix 75 + den.hosts.x86_64-linux.my-wsl = { 76 + intoAttr = "wslConfigurations"; 77 + users.vic = { }; 78 + }; 79 + ``` 80 + 81 + ## Main Module Resolution 82 + 83 + The bridge between Den's schema and final modules is the `mainModule`, 84 + computed internally as: 85 + 86 + ```mermaid 87 + graph TD 88 + Entity["host / home definition"] 89 + Entity -->|"ctx.host / ctx.home"| Intent["Apply context pipeline"] 90 + Intent -->|"aspect.resolve { class }"| Module["Single Nix module"] 91 + Module --> Instantiate["instantiate function"] 92 + Instantiate --> Output["flake.<intoAttr>.<name>"] 93 + ``` 94 + 95 + The context pipeline collects contributions from: 96 + - The entity's own aspect (host aspect or home aspect) 97 + - User aspects (for hosts with users) 98 + - `den.default` includes 99 + - Context-specific includes (`den.ctx.*.includes`) 100 + - Batteries and namespace aspects 101 + 102 + All contributions for the matching class are merged into one module. 103 + 104 + ## Without Flake-Parts 105 + 106 + When `inputs.flake-parts` is not present, Den provides a minimal 107 + `options.flake` definition so that configuration outputs have a place 108 + to be collected. This allows Den to work standalone or with any 109 + module evaluation system.
+112
docs/src/content/docs/reference/schema.md
··· 1 + --- 2 + title: Entity Schema Reference 3 + description: Host, user, and home configuration options. 4 + --- 5 + 6 + import { Aside } from '@astrojs/starlight/components'; 7 + 8 + <Aside type="tip">Source: [`modules/_types.nix`](https://github.com/vic/den/blob/main/modules/_types.nix) · [`modules/options.nix`](https://github.com/vic/den/blob/main/modules/options.nix)</Aside> 9 + 10 + ## den.hosts 11 + 12 + ```nix 13 + den.hosts.<system>.<name> = { ... }; 14 + ``` 15 + 16 + ### Host Options 17 + 18 + | Option | Type | Default | Description | 19 + |--------|------|---------|-------------| 20 + | `name` | str | attr name | Host configuration name | 21 + | `hostName` | str | `name` | Network hostname | 22 + | `system` | str | parent key | Platform (e.g., `x86_64-linux`) | 23 + | `class` | str | guessed | `nixos`, `darwin`, or `systemManager` | 24 + | `aspect` | str | `name` | Main aspect name | 25 + | `description` | str | auto | Human-readable description | 26 + | `users` | attrset | `{}` | User definitions | 27 + | `instantiate` | function | auto | Builder function | 28 + | `intoAttr` | str | auto | Flake output attribute | 29 + | `mainModule` | module | auto | Resolved NixOS/Darwin module | 30 + | *freeform* | anything | — | Custom attributes | 31 + 32 + ### Class Detection 33 + 34 + | System suffix | Default class | Default intoAttr | 35 + |--------------|---------------|------------------| 36 + | `*-linux` | `nixos` | `nixosConfigurations` | 37 + | `*-darwin` | `darwin` | `darwinConfigurations` | 38 + 39 + ### Instantiation 40 + 41 + | Class | Default function | 42 + |-------|-----------------| 43 + | `nixos` | `inputs.nixpkgs.lib.nixosSystem` | 44 + | `darwin` | `inputs.darwin.lib.darwinSystem` | 45 + | `systemManager` | `inputs.system-manager.lib.makeSystemConfig` | 46 + 47 + ## User Options 48 + 49 + ```nix 50 + den.hosts.<system>.<host>.users.<name> = { ... }; 51 + ``` 52 + 53 + | Option | Type | Default | Description | 54 + |--------|------|---------|-------------| 55 + | `name` | str | attr name | User configuration name | 56 + | `userName` | str | `name` | OS account name | 57 + | `class` | str | `homeManager` | Home management class | 58 + | `aspect` | str | `name` | Main aspect name | 59 + | *freeform* | anything | — | Custom attributes | 60 + 61 + ## den.homes 62 + 63 + ```nix 64 + den.homes.<system>.<name> = { ... }; 65 + ``` 66 + 67 + ### Home Options 68 + 69 + | Option | Type | Default | Description | 70 + |--------|------|---------|-------------| 71 + | `name` | str | attr name | Home configuration name | 72 + | `userName` | str | `name` | User account name | 73 + | `system` | str | parent key | Platform system | 74 + | `class` | str | `homeManager` | Home management class | 75 + | `aspect` | str | `name` | Main aspect name | 76 + | `description` | str | auto | Human-readable description | 77 + | `pkgs` | attrset | auto | Nixpkgs instance | 78 + | `instantiate` | function | auto | Builder function | 79 + | `intoAttr` | str | `homeConfigurations` | Flake output attribute | 80 + | `mainModule` | module | auto | Resolved HM module | 81 + | *freeform* | anything | — | Custom attributes | 82 + 83 + ## den.base 84 + 85 + Base modules applied to all entities of a type: 86 + 87 + ```nix 88 + den.base.conf = { ... }: { }; # hosts + users + homes 89 + den.base.host = { host, ... }: { }; 90 + den.base.user = { user, ... }: { }; 91 + den.base.home = { home, ... }: { }; 92 + ``` 93 + 94 + `den.base.conf` is automatically imported by host, user, and home. 95 + 96 + ## den.ful 97 + 98 + Namespace storage for aspect libraries: 99 + 100 + ```nix 101 + den.ful.<namespace>.<name> = aspect; 102 + ``` 103 + 104 + Populated via [`inputs.den.namespace`](/guides/namespaces/). 105 + 106 + ## flake.denful 107 + 108 + Flake output for sharing namespaces: 109 + 110 + ```nix 111 + flake.denful.<namespace> = den.ful.<namespace>; 112 + ```
+115
docs/src/content/docs/tutorials/context-aware.md
··· 1 + --- 2 + title: Context-Aware Configurations 3 + description: Make aspects produce conditional config based on host and user context. 4 + --- 5 + 6 + ## From Static to Dynamic 7 + 8 + So far, aspects have been static attribute sets. But Den's power comes from 9 + making them **functions of context**. When an aspect is a function, Den 10 + passes it the current context — host, user, platform — and the function 11 + decides what to produce. 12 + 13 + ## Step 1: A Simple Context Function 14 + 15 + Instead of a static aspect, write a function: 16 + 17 + ```nix 18 + { den, ... }: { 19 + den.aspects.igloo.includes = [ 20 + ({ host, ... }: { 21 + nixos.networking.hostName = host.name; 22 + }) 23 + ]; 24 + } 25 + ``` 26 + 27 + Den calls this function with `{ host }` containing the host's attributes. 28 + The result sets the hostname dynamically from the host's name. 29 + 30 + ## Step 2: React to User Context 31 + 32 + Functions receiving `{ host, user, ... }` run once per user on each host: 33 + 34 + ```nix 35 + { den, ... }: { 36 + den.default.includes = [ 37 + ({ host, user, ... }: { 38 + ${host.class}.users.users.${user.userName}.description = 39 + "${user.userName} on ${host.name}"; 40 + }) 41 + ]; 42 + } 43 + ``` 44 + 45 + Notice `${host.class}` — this dynamically targets `nixos` or `darwin` 46 + depending on the host's platform. The same function works on both. 47 + 48 + ## Step 3: Conditional Configuration 49 + 50 + Use standard Nix conditionals inside context functions: 51 + 52 + ```nix 53 + { den, lib, ... }: 54 + let 55 + git-for-linux = { user, host, ... }: 56 + if !lib.hasSuffix "darwin" host.system 57 + then { homeManager.programs.git.enable = true; } 58 + else { }; 59 + in { 60 + den.aspects.tux.includes = [ git-for-linux ]; 61 + } 62 + ``` 63 + 64 + Git is enabled only for users on Linux hosts. On Darwin, the function 65 + returns an empty set — no effect. 66 + 67 + ## Step 4: Use den.lib.parametric 68 + 69 + For aspects that need to forward context to their own includes, 70 + wrap them with `den.lib.parametric`: 71 + 72 + ```nix 73 + { den, ... }: 74 + let 75 + workspace = den.lib.parametric { 76 + nixos.networking.hostName = "from-parametric"; 77 + includes = [ 78 + ({ host, ... }: { nixos.time.timeZone = "UTC"; }) 79 + ]; 80 + }; 81 + in { 82 + den.aspects.igloo.includes = [ workspace ]; 83 + } 84 + ``` 85 + 86 + The `parametric` functor ensures that: 87 + 1. **Owned** config (`nixos.networking.hostName`) is always included 88 + 2. **Functions** in `includes` receive the forwarded context 89 + 3. Functions whose parameters don't match are **silently skipped** 90 + 91 + ## Step 5: Understand Matching 92 + 93 + Den matches context by **argument names**, not values: 94 + 95 + | Function signature | `{ host }` | `{ host, user }` | 96 + |--------------------|:---:|:---:| 97 + | `{ host, ... }: ...` | ✓ | ✓ | 98 + | `{ host, user }: ...` | ✗ | ✓ | 99 + | `{ never, ... }: ...` | ✗ | ✗ | 100 + 101 + - `atLeast` — function is called if context has **at least** the required args 102 + - `exactly` — function is called only if context has **exactly** those args 103 + 104 + ## What You've Learned 105 + 106 + - Aspects can be functions that receive `{ host, user, home, ... }` 107 + - Context functions produce conditional, platform-aware configurations 108 + - [`den.lib.parametric`](/explanation/parametric/) forwards context to nested includes 109 + - Unmatched functions are [silently skipped](/explanation/parametric/#matching-rules-summary) — no errors 110 + - `${host.class}` makes configs target the right Nix class dynamically 111 + 112 + ## Next 113 + 114 + - [Bidirectional Dependencies](/guides/bidirectional/) — hosts and users configure each other 115 + - [Context System](/explanation/context-system/) — deep dive into `den.ctx`
+114
docs/src/content/docs/tutorials/first-aspect.md
··· 1 + --- 2 + title: Your First Aspect 3 + description: Create a cross-class, reusable Nix configuration aspect. 4 + --- 5 + 6 + ## What is an Aspect? 7 + 8 + An aspect is a composable bundle of Nix configurations that can span multiple 9 + classes (NixOS, Darwin, Home-Manager). Each host, user, and home you declare 10 + automatically gets an aspect. 11 + 12 + ## Step 1: Declare Your Infrastructure 13 + 14 + Start with a host and user: 15 + 16 + ```nix 17 + # modules/hosts.nix 18 + { 19 + den.hosts.x86_64-linux.igloo.users.tux = { }; 20 + } 21 + ``` 22 + 23 + Den creates `den.aspects.igloo` (host) and `den.aspects.tux` (user) automatically. 24 + 25 + ## Step 2: Configure the Host Aspect 26 + 27 + Any module file can contribute to any aspect. Create a file for your host: 28 + 29 + ```nix 30 + # modules/igloo.nix 31 + { den, ... }: { 32 + den.aspects.igloo = { 33 + nixos.networking.hostName = "igloo"; 34 + nixos.time.timeZone = "UTC"; 35 + homeManager.programs.direnv.enable = true; 36 + }; 37 + } 38 + ``` 39 + 40 + The `nixos` settings apply to NixOS. The `homeManager` settings apply 41 + to **every user** on this host. 42 + 43 + ## Step 3: Configure the User Aspect 44 + 45 + ```nix 46 + # modules/vic.nix 47 + { den, ... }: { 48 + den.aspects.tux = { 49 + homeManager.programs.fish.enable = true; 50 + nixos.users.users.tux.description = "Tux the Penguin"; 51 + }; 52 + } 53 + ``` 54 + 55 + User aspects contribute to **every host** that has this user. 56 + If `tux` exists on both `igloo` and another host, both get the fish config. 57 + 58 + ## Step 4: Use Includes for Composition 59 + 60 + Aspects can include other aspects: 61 + 62 + ```nix 63 + # modules/gaming.nix 64 + { den, ... }: { 65 + den.aspects.gaming = { 66 + nixos.programs.steam.enable = true; 67 + homeManager.programs.mangohud.enable = true; 68 + }; 69 + 70 + den.aspects.igloo.includes = [ den.aspects.gaming ]; 71 + } 72 + ``` 73 + 74 + ## Step 5: Use Provides for Nesting 75 + 76 + Organize related aspects in a tree: 77 + 78 + ```nix 79 + { den, ... }: { 80 + den.aspects.tools.provides.editors = { 81 + homeManager.programs.vim.enable = true; 82 + }; 83 + 84 + den.aspects.tux.includes = [ den.aspects.tools._.editors ]; 85 + } 86 + ``` 87 + 88 + The `._. ` syntax is shorthand for `.provides.`. 89 + 90 + ## Step 6: Set Global Defaults 91 + 92 + Use `den.default` for settings shared across all hosts and users: 93 + 94 + ```nix 95 + # modules/defaults.nix 96 + { 97 + den.default.homeManager.home.stateVersion = "25.11"; 98 + den.default.nixos.system.stateVersion = "25.11"; 99 + } 100 + ``` 101 + 102 + ## What You've Learned 103 + 104 + - [Aspects](/explanation/aspects/) bundle cross-class configs (nixos, darwin, homeManager) 105 + - Host aspects apply to all users on that host 106 + - User aspects apply to all hosts with that user 107 + - `includes` compose aspects together 108 + - `provides` creates nested aspect trees 109 + - [`den.default`](/explanation/context-pipeline/#dendefault-is-an-alias) sets global shared values 110 + 111 + ## Next 112 + 113 + [Context-Aware Configs](/tutorials/context-aware/) — make your aspects 114 + respond dynamically to their host and user context.
+97
docs/src/content/docs/tutorials/getting-started.md
··· 1 + --- 2 + title: Getting Started 3 + description: Set up your first Den project from scratch. 4 + --- 5 + 6 + ## Prerequisites 7 + 8 + - [Nix](https://nixos.org/download) with flakes enabled (or use [without flakes](/guides/no-flakes/)) 9 + - Basic familiarity with Nix modules 10 + 11 + ## Quick Start — Launch the Demo VM 12 + 13 + Try Den instantly without installing anything: 14 + 15 + ```console 16 + nix run github:vic/den 17 + ``` 18 + 19 + ## Initialize a New Project 20 + 21 + Create a fresh Den-based flake: 22 + 23 + ```console 24 + mkdir my-infra && cd my-infra 25 + nix flake init -t github:vic/den 26 + nix flake update den 27 + ``` 28 + 29 + This creates a project with: 30 + 31 + ``` 32 + flake.nix # inputs and entry point 33 + modules/ # your Den modules go here 34 + hosts.nix # host and user declarations 35 + aspects/ # aspect definitions 36 + ``` 37 + 38 + ## Your flake.nix 39 + 40 + The generated `flake.nix` imports Den and uses `import-tree` to load all modules: 41 + 42 + ```nix 43 + { 44 + outputs = inputs: 45 + inputs.flake-parts.lib.mkFlake { inherit inputs; } 46 + (inputs.import-tree ./modules); 47 + 48 + inputs = { 49 + den.url = "github:vic/den"; 50 + flake-aspects.url = "github:vic/flake-aspects"; 51 + import-tree.url = "github:vic/import-tree"; 52 + nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; 53 + flake-parts.url = "github:hercules-ci/flake-parts"; 54 + }; 55 + } 56 + ``` 57 + 58 + ## Declare a Host 59 + 60 + In `modules/hosts.nix`, declare your first host: 61 + 62 + ```nix 63 + { 64 + den.hosts.x86_64-linux.my-laptop.users.vic = { }; 65 + } 66 + ``` 67 + 68 + This single line creates: 69 + - A NixOS host named `my-laptop` on `x86_64-linux` 70 + - A user `vic` with Home-Manager support 71 + - Aspects `den.aspects.my-laptop` and `den.aspects.vic` 72 + 73 + ## Build It 74 + 75 + ```console 76 + nixos-rebuild switch --flake .#my-laptop 77 + ``` 78 + 79 + ## Available Templates 80 + 81 + | Template | Description | 82 + |----------|-------------| 83 + | `default` | Batteries-included layout | 84 + | `minimal` | Minimalistic Den flake | 85 + | `noflake` | No flakes, no flake-parts | 86 + | `example` | Examples and patterns | 87 + | `ci` | Feature test suite | 88 + | `bogus` | Bug reproduction | 89 + 90 + ```console 91 + nix flake init -t github:vic/den#minimal 92 + ``` 93 + 94 + ## Next Steps 95 + 96 + - [Your First Aspect](/tutorials/first-aspect/) — write cross-class configs 97 + - [Context-Aware Configs](/tutorials/context-aware/) — make aspects react to context
+5
docs/tsconfig.json
··· 1 + { 2 + "extends": "astro/tsconfigs/strict", 3 + "include": [".astro/types.d.ts", "**/*"], 4 + "exclude": ["dist"] 5 + }
+4 -8
modules/_types.nix
··· 91 91 visible = false; 92 92 readOnly = true; 93 93 type = lib.types.deferredModule; 94 - default = mainModule config "OS" "host"; 94 + default = mainModule config den.ctx.host "host"; 95 95 }; 96 96 }; 97 97 } ··· 196 196 visible = false; 197 197 readOnly = true; 198 198 type = lib.types.deferredModule; 199 - default = mainModule config "HM" "home"; 199 + default = mainModule config den.ctx.home "home"; 200 200 }; 201 201 }; 202 202 } ··· 205 205 mainModule = 206 206 from: intent: name: 207 207 let 208 - asp = den.aspects.${from.aspect}; 209 - ctx = { 210 - ${intent} = asp; 211 - ${name} = from; 212 - }; 213 - mod = (asp ctx).resolve { inherit (from) class; }; 208 + asp = intent { ${name} = from; }; 209 + mod = asp.resolve { inherit (from) class; }; 214 210 in 215 211 mod; 216 212 in
+8 -6
modules/aspects/defaults.nix
··· 1 - # creates den.default aspect 2 - { lib, den, ... }: 3 1 { 4 - config.den.default = den.lib.parametric.atLeast { }; 5 - options.den.default = lib.mkOption { 6 - type = den.lib.aspects.types.aspectSubmodule; 7 - }; 2 + den = 3 + { lib, ... }: 4 + { 5 + imports = [ (lib.mkAliasOptionModule [ "default" ] [ "ctx" "default" ]) ]; 6 + 7 + ctx.default.conf = _: { }; 8 + 9 + }; 8 10 }
+1 -4
modules/aspects/definition.nix
··· 8 8 inherit (den.lib) parametric; 9 9 10 10 makeAspect = from: { 11 - ${from.aspect} = parametric.atLeast { 12 - ${from.class} = { }; 13 - includes = [ den.default ]; 14 - }; 11 + ${from.aspect} = parametric { ${from.class} = { }; }; 15 12 }; 16 13 17 14 hosts = map builtins.attrValues (builtins.attrValues den.hosts);
-52
modules/aspects/dependencies.nix
··· 1 - { 2 - den, 3 - ... 4 - }: 5 - let 6 - inherit (den.lib) 7 - owned 8 - statics 9 - take 10 - ; 11 - 12 - dependencies = [ 13 - (take.exactly osDependencies) 14 - ]; 15 - 16 - osDependencies = 17 - { OS, host }: 18 - { 19 - includes = [ 20 - (owned den.default) 21 - (statics den.default) 22 - (owned OS) 23 - (statics OS) 24 - { 25 - includes = 26 - let 27 - users = builtins.attrValues host.users; 28 - contrib = osUserDependencies { inherit OS host; }; 29 - in 30 - map contrib users; 31 - } 32 - ]; 33 - }; 34 - 35 - osUserDependencies = 36 - { OS, host }: 37 - user: 38 - let 39 - USR = den.aspects.${user.aspect}; 40 - in 41 - { 42 - includes = [ 43 - (owned USR) 44 - (statics USR) 45 - (USR { inherit OS host user; }) 46 - ]; 47 - }; 48 - 49 - in 50 - { 51 - den.default.includes = dependencies; 52 - }
-9
modules/aspects/provides/ci-noboot.nix
··· 1 - { config, lib, ... }: 2 - { 3 - den.default.includes = lib.optionals (config ? _module.args.CI) [ 4 - { 5 - nixos.fileSystems."/".device = lib.mkDefault "/dev/noroot"; 6 - nixos.boot.loader.grub.enable = lib.mkDefault false; 7 - } 8 - ]; 9 - }
+5 -1
modules/aspects/provides/define-user.nix
··· 25 25 userContext = 26 26 { host, user, ... }: 27 27 { 28 - nixos.users.users.${user.userName}.isNormalUser = true; 28 + nixos.users.users.${user.userName} = { 29 + name = user.userName; 30 + home = homeDir host user; 31 + isNormalUser = true; 32 + }; 29 33 darwin.users.users.${user.userName} = { 30 34 name = user.userName; 31 35 home = homeDir host user;
+3 -4
modules/aspects/provides/flake-parts/inputs.nix
··· 37 37 } 38 38 ); 39 39 40 - osAspect = { OS, host }: unused OS (mkAspect host.class host.system); 40 + osAspect = { host }: mkAspect host.class host.system; 41 41 42 42 userAspect = 43 43 { 44 - HM, 45 44 user, 46 45 host, 47 46 }: 48 - unused HM (mkAspect user.class host.system); 47 + mkAspect user.class host.system; 49 48 50 - hmAspect = { HM, home }: unused HM (mkAspect home.class home.system); 49 + hmAspect = { home }: mkAspect home.class home.system; 51 50 52 51 in 53 52 {
+3 -4
modules/aspects/provides/flake-parts/self.nix
··· 37 37 } 38 38 ); 39 39 40 - osAspect = { OS, host }: unused OS (mkAspect host.class host.system); 40 + osAspect = { host }: mkAspect host.class host.system; 41 41 42 42 userAspect = 43 43 { 44 - HM, 45 44 user, 46 45 host, 47 46 }: 48 - unused HM (mkAspect user.class host.system); 47 + mkAspect user.class host.system; 49 48 50 - homeAspect = { HM, home }: unused HM (mkAspect home.class home.system); 49 + homeAspect = { home }: mkAspect home.class home.system; 51 50 in 52 51 { 53 52 den.provides.self' = parametric.exactly {
-49
modules/aspects/provides/home-manager/hm-dependencies.nix
··· 1 - { 2 - den, 3 - ... 4 - }: 5 - let 6 - inherit (den.lib) 7 - owned 8 - statics 9 - parametric 10 - take 11 - ; 12 - 13 - dependencies = [ 14 - (take.exactly hmUserDependencies) 15 - (take.exactly hmStandaloneDependencies) 16 - ]; 17 - 18 - # from OS home-managed integration. 19 - hmUserDependencies = 20 - { HM-OS-USER }: 21 - let 22 - inherit (HM-OS-USER) OS HM; 23 - hostCtx = { inherit (HM-OS-USER) OS host user; }; 24 - userCtx = { inherit (HM-OS-USER) HM host user; }; 25 - in 26 - { 27 - includes = [ 28 - (owned den.default) 29 - (statics den.default) 30 - (parametric.fixedTo hostCtx OS) 31 - (parametric.fixedTo userCtx HM) 32 - ]; 33 - }; 34 - 35 - hmStandaloneDependencies = 36 - { HM, home }: 37 - take.unused home { 38 - includes = [ 39 - (owned den.default) 40 - (statics den.default) 41 - (owned HM) 42 - (statics HM) 43 - ]; 44 - }; 45 - 46 - in 47 - { 48 - den.default.includes = dependencies; 49 - }
+42 -57
modules/aspects/provides/home-manager/hm-integration.nix
··· 5 5 ... 6 6 }: 7 7 let 8 + inherit (den.lib) parametric; 9 + 8 10 description = '' 9 11 integrates home-manager into nixos/darwin OS classes. 10 12 11 - usage: 12 - 13 - for using home-manager in just a particular host: 14 - 15 - den.aspects.my-laptop.includes = [ den._.home-manager ]; 16 - 17 - for enabling home-manager by default on all hosts: 18 - 19 - den.default.includes = [ den._.home-manager ]; 20 - 21 13 Does nothing for hosts that have no users with `homeManager` class. 22 14 Expects `inputs.home-manager` to exist. If `<host>.hm-module` exists 23 15 it is the home-manager.{nixos/darwin}Modules.home-manager. 24 16 25 - For each user resolves den.aspects.''${user.aspect} and imports its homeManager class module. 17 + For each user produces a `den.ctx.hm` context, and 18 + forwards the `homeManager` class into os-level 19 + `home-manager.home-manager.users.<user>` 26 20 ''; 27 21 28 - homeManager = 29 - { HM-OS-HOST }: 30 - let 31 - inherit (HM-OS-HOST) OS host; 22 + hmClass = "homeManager"; 32 23 33 - hmClass = "homeManager"; 34 - hmModule = host.hm-module or inputs.home-manager."${host.class}Modules".home-manager; 35 - hmUsers = lib.filter (u: u.class == hmClass) (lib.attrValues host.users); 24 + intoHmUsers = 25 + { host }: 26 + map (user: { inherit host user; }) (lib.filter (u: u.class == hmClass) (lib.attrValues host.users)); 36 27 37 - hmUserAspect = 38 - user: 39 - let 40 - HM = den.aspects.${user.aspect}; 41 - HM-OS-USER = { 42 - inherit 43 - OS 44 - HM 45 - host 46 - user 47 - ; 48 - }; 49 - in 50 - HM { inherit HM-OS-USER; }; 51 - 52 - hmUsersAspect = 53 - { class, aspect-chain }: 54 - den._.forward { 55 - each = lib.optionals (lib.elem class [ 56 - "nixos" 57 - "darwin" 58 - ]) hmUsers; 59 - fromClass = _: hmClass; 60 - fromAspect = den.lib.take.unused aspect-chain hmUserAspect; 61 - intoClass = _: class; 62 - intoPath = user: [ 63 - "home-manager" 64 - "users" 65 - user.userName 66 - ]; 67 - }; 68 - in 69 - { 70 - ${host.class}.imports = [ hmModule ]; 71 - includes = [ hmUsersAspect ]; 28 + forwardedToHost = 29 + { host, user }: 30 + den._.forward { 31 + each = lib.singleton true; 32 + fromClass = _: hmClass; 33 + intoClass = _: host.class; 34 + intoPath = _: [ 35 + "home-manager" 36 + "users" 37 + user.userName 38 + ]; 39 + fromAspect = _: (den.ctx.hm-internal-user { inherit host user; }); 72 40 }; 73 41 74 42 in 75 43 { 76 - den.provides.home-manager = { 77 - inherit description; 78 - __functor = _: den.lib.take.exactly homeManager; 79 - }; 44 + den.provides.home-manager = { }; 45 + 46 + den.ctx.home.desc = "Standalone Home-Manager config provided by home aspect"; 47 + den.ctx.home.conf = { home }: parametric.fixedTo { inherit home; } den.aspects.${home.aspect}; 48 + den.ctx.home.into.default = lib.singleton; 49 + 50 + den.ctx.hm-host.into.hm-user = intoHmUsers; 51 + den.ctx.hm-user.desc = "(internal)"; 52 + den.ctx.hm-user.conf = forwardedToHost; 53 + 54 + den.ctx.hm-internal-user.conf = 55 + { host, user }: 56 + { class, aspect-chain }: 57 + { 58 + includes = [ 59 + (den.ctx.user { inherit host user; }) 60 + (den.lib.owned den.aspects.${host.aspect}) 61 + (den.lib.statics den.aspects.${host.aspect} { inherit class aspect-chain; }) 62 + (parametric.atLeast den.aspects.${host.aspect} { inherit host user; }) 63 + ]; 64 + }; 80 65 }
-43
modules/aspects/provides/home-manager/hm-os-host.nix
··· 1 - { den, lib, ... }: 2 - let 3 - description = '' 4 - This is a private aspect always included in den.default. 5 - 6 - This aspect detects hosts that have an HM supported OS and 7 - that have at least one user with ${hm-class} class. 8 - 9 - When this occurs it produces a context `HM-OS-HOST` 10 - that other host aspects can use. 11 - 12 - When the `den._.home-manager` aspect is enabled by the user, 13 - it reacts to this context and configures HM on the host. 14 - 15 - This same context can be used by other aspects to configure 16 - OS settings ONLY for hosts having HM enabled. 17 - ''; 18 - 19 - hm-class = "homeManager"; 20 - hm-os-classes = [ 21 - "nixos" 22 - "darwin" 23 - ]; 24 - 25 - hm-detect = 26 - { OS, host }: 27 - let 28 - is-os-supported = builtins.elem host.class hm-os-classes; 29 - hm-users = builtins.filter (u: u.class == hm-class) (lib.attrValues host.users); 30 - has-hm-users = builtins.length hm-users > 0; 31 - is-hm-host = is-os-supported && has-hm-users; 32 - ctx.HM-OS-HOST = { inherit OS host; }; 33 - in 34 - if is-hm-host then OS ctx else { }; 35 - 36 - aspect = { 37 - inherit description; 38 - __functor = _: den.lib.take.exactly hm-detect; 39 - }; 40 - in 41 - { 42 - den.default.includes = [ aspect ]; 43 - }
+52
modules/aspects/provides/home-manager/hm-os.nix
··· 1 + { 2 + den, 3 + lib, 4 + inputs, 5 + ... 6 + }: 7 + let 8 + description = '' 9 + Detects hosts that have an HM supported OS and 10 + that have at least one user with ${hm-class} class. 11 + 12 + When this occurs it produces a context `den.ctx.hm-os` 13 + 14 + This `den.ctx.hm-os` context includes the OS-level 15 + homeManager module and is used by hm-integration.nix to then 16 + produce a `den.ctx.hm` for each user. 17 + 18 + This same context can be used to include aspects 19 + ONLY for hosts having HM enabled. 20 + 21 + den.ctx.hm-os.includes = [ den.aspects.foo ]; 22 + ''; 23 + 24 + hm-class = "homeManager"; 25 + hm-os-classes = [ 26 + "nixos" 27 + "darwin" 28 + ]; 29 + hm-module = host: host.hm-module or inputs.home-manager."${host.class}Modules".home-manager; 30 + 31 + hm-detect = 32 + { host }: 33 + let 34 + is-os-supported = builtins.elem host.class hm-os-classes; 35 + has-hm-module = (host ? hm-module) || (inputs ? home-manager); 36 + hm-users = builtins.filter (u: u.class == hm-class) (lib.attrValues host.users); 37 + has-hm-users = builtins.length hm-users > 0; 38 + is-hm-host = is-os-supported && has-hm-users && has-hm-module; 39 + in 40 + lib.optional is-hm-host { inherit host; }; 41 + 42 + in 43 + { 44 + den.ctx.host.into.hm-host = hm-detect; 45 + 46 + den.ctx.hm-host.desc = description; 47 + den.ctx.hm-host.conf = 48 + { host }: 49 + { 50 + ${host.class}.imports = [ (hm-module host) ]; 51 + }; 52 + }
+3 -3
modules/aspects/provides/import-tree.nix
··· 48 48 or it can be default imported per host/user/home: 49 49 50 50 # load from ./hosts/<host>/_nixos 51 - den.default.includes = [ (den._.import-tree._.host ./hosts) ]; 51 + den.ctx.os.includes = [ (den._.import-tree._.host ./hosts) ]; 52 52 53 53 # load from ./users/<user>/{_homeManager, _nixos} 54 - den.default.includes = [ (den._.import-tree._.user ./users) ]; 54 + den.ctx.hm.includes = [ (den._.import-tree._.user ./users) ]; 55 55 56 56 # load from ./homes/<home>/_homeManager 57 - den.default.includes = [ (den._.import-tree._.home ./homes) ]; 57 + den.ctx.home.includes = [ (den._.import-tree._.home ./homes) ]; 58 58 59 59 you are also free to create your own auto-imports layout following the implementation of these. 60 60 '';
+18 -11
modules/aspects/provides/unfree/unfree-predicate-builder.nix
··· 30 30 }; 31 31 }; 32 32 33 - osAspect = { OS, host }: take.unused OS { ${host.class}.imports = [ unfreeModule ]; }; 34 - 35 - userAspect = 33 + osAspect = take.exactly ( 34 + { host }: 35 + { 36 + ${host.class}.imports = [ unfreeModule ]; 37 + } 38 + ); 39 + userAspect = take.exactly ( 40 + { host, user }: 41 + { 42 + ${user.class}.imports = [ unfreeModule ]; 43 + } 44 + ); 45 + homeAspect = take.exactly ( 46 + { home }: 36 47 { 37 - HM, 38 - user, 39 - host, 40 - }: 41 - take.unused [ HM host ] { ${user.class}.imports = [ unfreeModule ]; }; 48 + ${home.class}.imports = [ unfreeModule ]; 49 + } 50 + ); 42 51 43 - homeAspect = { HM, home }: take.unused HM { ${home.class}.imports = [ unfreeModule ]; }; 44 - 45 - aspect = parametric.exactly { 52 + aspect = parametric { 46 53 inherit description; 47 54 includes = [ 48 55 osAspect
+31
modules/context/os.nix
··· 1 + { den, lib, ... }: 2 + let 3 + inherit (den.lib.parametric) fixedTo atLeast; 4 + 5 + ctx.host.desc = "OS"; 6 + ctx.host.conf = { host }: fixedTo { inherit host; } den.aspects.${host.aspect}; 7 + 8 + ctx.host.into.default = lib.singleton; 9 + ctx.host.into.user = { host }: map (user: { inherit host user; }) (lib.attrValues host.users); 10 + 11 + ctx.user.desc = "OS user"; 12 + ctx.user.conf = 13 + { host, user }@ctx: 14 + { 15 + includes = 16 + let 17 + hostAspect = den.aspects.${host.aspect}; 18 + userAspect = den.aspects.${user.aspect}; 19 + in 20 + [ 21 + (fixedTo ctx userAspect) 22 + (atLeast hostAspect ctx) 23 + ]; 24 + }; 25 + 26 + ctx.user.into.default = lib.singleton; 27 + 28 + in 29 + { 30 + config.den.ctx = ctx; 31 + }
+118
modules/context/types.nix
··· 1 + # den.ctx — Declarative context definitions. 2 + # 3 + # A context is an attribute set whose attrNames (not values) determine 4 + # which parametric functions match. den.ctx provides named context 5 + # types with declarative transformations and aspect lookup. 6 + # 7 + # Named contexts carry semantic meaning beyond their structure. 8 + # ctx.host { host } and ctx.hm-host { host } hold the same data, 9 + # but hm-host guarantees home-manager support was validated — 10 + # following transform-don't-validate: you cannot obtain an hm-host 11 + # unless all detection criteria passed. 12 + # 13 + # Context types are independent of NixOS. Den can be used as a library 14 + # for any domain configurable through Nix (cloud infra, containers, 15 + # helm charts, etc). The OS framework is one implementation on top of 16 + # this context+aspects library. 17 + # 18 + # Shape of a context definition: 19 + # 20 + # den.ctx.foobar = { 21 + # desc = "The {foo,bar} context"; 22 + # conf = { foo, bar }: den.aspects.${foo}._.${bar}; 23 + # includes = [ <parametric aspects for this context> ]; 24 + # into = { 25 + # baz = { foo, bar }: lib.singleton { baz = 22; }; 26 + # }; 27 + # }; 28 + # 29 + # A context type is callable (it is a functor): 30 + # 31 + # aspect = den.ctx.foobar { foo = "hello"; bar = "world"; }; 32 + # 33 + # ctxApply produces an aspect that includes: owned configs from the 34 + # context type itself, the located aspect via conf, and all recursive 35 + # transformations via into. 36 + # 37 + # Transformations have type: source -> [ target ]. This allows fan-out 38 + # (one host producing many { host, user } pairs via map) and conditional 39 + # propagation (lib.optional for detection gates like hm-host). 40 + # 41 + # den.default is an alias for den.ctx.default. Every context type 42 + # transforms into default, so den.default.includes runs at every 43 + # pipeline stage. Use take.exactly to restrict matching. 44 + # 45 + # See os.nix, defaults.nix and provides/home-manager/ for built-in 46 + # context types. 47 + { den, lib, ... }: 48 + let 49 + inherit (den.lib) parametric take; 50 + inherit (den.lib.aspects.types) providerType; 51 + 52 + ctxType = lib.types.submodule { 53 + freeformType = lib.types.lazyAttrsOf lib.types.deferredModule; 54 + options = { 55 + desc = lib.mkOption { 56 + description = "Context description"; 57 + type = lib.types.str; 58 + default = ""; 59 + }; 60 + conf = lib.mkOption { 61 + description = "Obtain a configuration aspect for context"; 62 + type = lib.types.functionTo providerType; 63 + default = { }; 64 + }; 65 + into = lib.mkOption { 66 + description = "Context transformations"; 67 + type = lib.types.lazyAttrsOf (lib.types.functionTo (lib.types.listOf lib.types.raw)); 68 + default = { }; 69 + }; 70 + includes = lib.mkOption { 71 + description = "List of parametric aspects to include for this context"; 72 + type = lib.types.listOf providerType; 73 + default = [ ]; 74 + }; 75 + __functor = lib.mkOption { 76 + description = "Apply context. Returns a aspect with all dependencies."; 77 + type = lib.types.functionTo (lib.types.functionTo providerType); 78 + readOnly = true; 79 + internal = true; 80 + visible = false; 81 + default = ctxApply; 82 + }; 83 + }; 84 + }; 85 + 86 + cleanCtx = 87 + ctx: 88 + builtins.removeAttrs ctx [ 89 + "desc" 90 + "conf" 91 + "into" 92 + "__functor" 93 + ]; 94 + 95 + # Given a context, returns an aspect that also includes 96 + # the result of all context propagation. 97 + ctxApply = 98 + self: ctx: 99 + let 100 + myself = parametric.fixedTo ctx (cleanCtx self); 101 + located = self.conf ctx; 102 + adapted = lib.mapAttrsToList (name: into: map den.ctx.${name} (into ctx)) self.into; 103 + in 104 + { 105 + includes = lib.flatten [ 106 + myself 107 + located 108 + adapted 109 + ]; 110 + }; 111 + 112 + in 113 + { 114 + options.den.ctx = lib.mkOption { 115 + default = { }; 116 + type = lib.types.lazyAttrsOf ctxType; 117 + }; 118 + }
+1
nix/lib.nix
··· 111 111 isFn 112 112 canTake 113 113 take 114 + isStatic 114 115 ; 115 116 }; 116 117 in
+6 -6
templates/bogus/flake.lock
··· 2 2 "nodes": { 3 3 "den": { 4 4 "locked": { 5 - "lastModified": 1771153332, 6 - "narHash": "sha256-oAzd3u2CsFxJXwZ1Mak2kJuAxKJUET7+nWLGWvdq5Jw=", 5 + "lastModified": 1771364340, 6 + "narHash": "sha256-i6IoHdOqdJHjJHuTIZqPJVDn6VVOG1nyRXR70qYQej4=", 7 7 "owner": "vic", 8 8 "repo": "den", 9 - "rev": "933a84fd1e1b625eaa20e160704f83cdbf13efd9", 9 + "rev": "f8cb8c618e1680e99c165d2bf826600170abb5a2", 10 10 "type": "github" 11 11 }, 12 12 "original": { ··· 18 18 }, 19 19 "flake-aspects": { 20 20 "locked": { 21 - "lastModified": 1771325453, 22 - "narHash": "sha256-a50O/36ySKext94tOnv7ucfLD75C1aHTWP+Um0w35R0=", 21 + "lastModified": 1771395573, 22 + "narHash": "sha256-bcCOG2CW23/Eww/zULJf1xd0Shz2zS4c2AJWwLALyJ8=", 23 23 "owner": "vic", 24 24 "repo": "flake-aspects", 25 - "rev": "cb78001b60fb34b8fabb8f78b082a6cf6c8a548d", 25 + "rev": "8297f3bc41ad79b9f01d56d0dd92f7aac51bacfb", 26 26 "type": "github" 27 27 }, 28 28 "original": {
+1 -2
templates/bogus/modules/test-base.nix
··· 17 17 den.default.homeManager.home.stateVersion = "26.05"; 18 18 19 19 den.default.includes = [ 20 - den.provides.home-manager 20 + den.aspects.no-boot 21 21 den.provides.define-user 22 - den.aspects.no-boot 23 22 ]; 24 23 25 24 den.aspects.no-boot.nixos = {
+28 -160
templates/ci/flake.lock
··· 1 1 { 2 2 "nodes": { 3 - "darwin": { 4 - "inputs": { 5 - "nixpkgs": [ 6 - "nixpkgs" 7 - ] 8 - }, 9 - "locked": { 10 - "lastModified": 1770736414, 11 - "narHash": "sha256-x5xdJgUxNflO9j2sJHIHnPujDy6eAWJPCMQml5y9XB4=", 12 - "owner": "nix-darwin", 13 - "repo": "nix-darwin", 14 - "rev": "7c952d9a524ffbbd5b5edca38fe6d943499585cc", 15 - "type": "github" 16 - }, 17 - "original": { 18 - "owner": "nix-darwin", 19 - "repo": "nix-darwin", 20 - "type": "github" 21 - } 22 - }, 23 3 "den": { 24 4 "locked": { 25 - "lastModified": 1771153332, 26 - "narHash": "sha256-oAzd3u2CsFxJXwZ1Mak2kJuAxKJUET7+nWLGWvdq5Jw=", 5 + "lastModified": 1771364340, 6 + "narHash": "sha256-i6IoHdOqdJHjJHuTIZqPJVDn6VVOG1nyRXR70qYQej4=", 27 7 "owner": "vic", 28 8 "repo": "den", 29 - "rev": "933a84fd1e1b625eaa20e160704f83cdbf13efd9", 9 + "rev": "f8cb8c618e1680e99c165d2bf826600170abb5a2", 30 10 "type": "github" 31 11 }, 32 12 "original": { ··· 37 17 }, 38 18 "flake-aspects": { 39 19 "locked": { 40 - "lastModified": 1771325453, 41 - "narHash": "sha256-a50O/36ySKext94tOnv7ucfLD75C1aHTWP+Um0w35R0=", 20 + "lastModified": 1771395573, 21 + "narHash": "sha256-bcCOG2CW23/Eww/zULJf1xd0Shz2zS4c2AJWwLALyJ8=", 42 22 "owner": "vic", 43 23 "repo": "flake-aspects", 44 - "rev": "cb78001b60fb34b8fabb8f78b082a6cf6c8a548d", 24 + "rev": "8297f3bc41ad79b9f01d56d0dd92f7aac51bacfb", 45 25 "type": "github" 46 26 }, 47 27 "original": { 48 28 "owner": "vic", 49 29 "repo": "flake-aspects", 50 - "type": "github" 51 - } 52 - }, 53 - "flake-file": { 54 - "locked": { 55 - "lastModified": 1770893152, 56 - "narHash": "sha256-DuZHf9EaQQ2iiUloYj4374VCsfDQ7kGuWC7037BDSpE=", 57 - "owner": "vic", 58 - "repo": "flake-file", 59 - "rev": "1515b77c3c1dd08ab394e840603fc152e059d13e", 60 - "type": "github" 61 - }, 62 - "original": { 63 - "owner": "vic", 64 - "repo": "flake-file", 65 30 "type": "github" 66 31 } 67 32 }, 68 33 "flake-parts": { 69 34 "inputs": { 70 35 "nixpkgs-lib": [ 71 - "nixpkgs-lib" 36 + "nixpkgs" 72 37 ] 73 38 }, 74 39 "locked": { ··· 92 57 ] 93 58 }, 94 59 "locked": { 95 - "lastModified": 1770818644, 96 - "narHash": "sha256-DYS4jIRpRoKOzJjnR/QqEd/MlT4OZZpt8CrBLv+cjsE=", 60 + "lastModified": 1771470818, 61 + "narHash": "sha256-Nh50ZnUK4/LY8D6We//rzT3oODBQK/gxXBoUcYJrmtg=", 97 62 "owner": "nix-community", 98 63 "repo": "home-manager", 99 - "rev": "0acbd1180697de56724821184ad2c3e6e7202cd7", 64 + "rev": "0f156f177da97604a9a91f4875a2ced7ba2941c5", 100 65 "type": "github" 101 66 }, 102 67 "original": { ··· 105 70 "type": "github" 106 71 } 107 72 }, 108 - "home-manager-stable": { 109 - "inputs": { 110 - "nixpkgs": [ 111 - "nixpkgs-stable" 112 - ] 113 - }, 114 - "locked": { 115 - "lastModified": 1763992789, 116 - "narHash": "sha256-WHkdBlw6oyxXIra/vQPYLtqY+3G8dUVZM8bEXk0t8x4=", 117 - "owner": "nix-community", 118 - "repo": "home-manager", 119 - "rev": "44831a7eaba4360fb81f2acc5ea6de5fde90aaa3", 120 - "type": "github" 121 - }, 122 - "original": { 123 - "owner": "nix-community", 124 - "ref": "release-25.05", 125 - "repo": "home-manager", 126 - "type": "github" 127 - } 128 - }, 129 73 "import-tree": { 130 74 "locked": { 131 - "lastModified": 1763762820, 132 - "narHash": "sha256-ZvYKbFib3AEwiNMLsejb/CWs/OL/srFQ8AogkebEPF0=", 75 + "lastModified": 1771045967, 76 + "narHash": "sha256-oYO4poyw0Sb/db2PigqugMlDwsvwLg6CSpFrMUWxA3Q=", 133 77 "owner": "vic", 134 78 "repo": "import-tree", 135 - "rev": "3c23749d8013ec6daa1d7255057590e9ca726646", 79 + "rev": "c968d3b54d12cf5d9c13f16f7c545a06c9d1fde6", 136 80 "type": "github" 137 81 }, 138 82 "original": { ··· 141 85 "type": "github" 142 86 } 143 87 }, 144 - "neovim-nightly-overlay": { 88 + "nix-unit": { 145 89 "inputs": { 146 90 "flake-parts": [ 147 91 "flake-parts" 148 92 ], 149 - "neovim-src": "neovim-src", 93 + "nix-github-actions": [], 150 94 "nixpkgs": [ 151 95 "nixpkgs" 152 - ] 153 - }, 154 - "locked": { 155 - "lastModified": 1770857573, 156 - "narHash": "sha256-pSeFA1qRAdivDrrKoybJ1DOcbkXx2v/ExIc6n0DbT4U=", 157 - "owner": "nix-community", 158 - "repo": "neovim-nightly-overlay", 159 - "rev": "31e79c73c444b2e51eb34f2305792809839c58e8", 160 - "type": "github" 96 + ], 97 + "treefmt-nix": [] 161 98 }, 162 - "original": { 163 - "owner": "nix-community", 164 - "repo": "neovim-nightly-overlay", 165 - "type": "github" 166 - } 167 - }, 168 - "neovim-src": { 169 - "flake": false, 170 99 "locked": { 171 - "lastModified": 1770810897, 172 - "narHash": "sha256-6F/Z/UQxalaSoqewSQ4fL8zSws3Vy4wgA5DgyTaeqTo=", 173 - "owner": "neovim", 174 - "repo": "neovim", 175 - "rev": "6b4ec2264e1d8ba027b85f3883d532c5068be92a", 176 - "type": "github" 177 - }, 178 - "original": { 179 - "owner": "neovim", 180 - "repo": "neovim", 181 - "type": "github" 182 - } 183 - }, 184 - "nixos-wsl": { 185 - "inputs": { 186 - "flake-compat": [], 187 - "nixpkgs": [ 188 - "nixpkgs-stable" 189 - ] 190 - }, 191 - "locked": { 192 - "lastModified": 1770657009, 193 - "narHash": "sha256-v/LA5ZSJ+JQYzMSKB4sySM0wKfsAqddNzzxLLnbsV/E=", 100 + "lastModified": 1762774186, 101 + "narHash": "sha256-hRADkHjNt41+JUHw2EiSkMaL4owL83g5ZppjYUdF/Dc=", 194 102 "owner": "nix-community", 195 - "repo": "nixos-wsl", 196 - "rev": "5b50ea1aaa14945d4794c80fcc99c4aa1db84d2d", 103 + "repo": "nix-unit", 104 + "rev": "1c9ab50554eed0b768f9e5b6f646d63c9673f0f7", 197 105 "type": "github" 198 106 }, 199 107 "original": { 200 108 "owner": "nix-community", 201 - "repo": "nixos-wsl", 109 + "repo": "nix-unit", 202 110 "type": "github" 203 111 } 204 112 }, 205 113 "nixpkgs": { 206 114 "locked": { 207 - "lastModified": 1770843696, 208 - "narHash": "sha256-9SFCZkVcpDOV6unH5hVEy4+dB0rxMuUoBnDAO6vshac=", 209 - "rev": "2343bbb58f99267223bc2aac4fc9ea301a155a16", 115 + "lastModified": 1771207753, 116 + "narHash": "sha256-7o+iRF++GO/gGrgrRMlnld2V/3QIzpdwMKViVkHtMEQ=", 117 + "rev": "d1c15b7d5806069da59e819999d70e1cec0760bf", 210 118 "type": "tarball", 211 - "url": "https://releases.nixos.org/nixpkgs/nixpkgs-26.05pre944764.2343bbb58f99/nixexprs.tar.xz" 119 + "url": "https://releases.nixos.org/nixpkgs/nixpkgs-26.05pre946960.d1c15b7d5806/nixexprs.tar.xz" 212 120 }, 213 121 "original": { 214 122 "type": "tarball", 215 123 "url": "https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.xz" 216 - } 217 - }, 218 - "nixpkgs-stable": { 219 - "locked": { 220 - "lastModified": 1768649915, 221 - "narHash": "sha256-jc21hKogFnxU7KXSVTRmxC7u5D4RHwm9BAvDf5/Z1Uo=", 222 - "owner": "nixos", 223 - "repo": "nixpkgs", 224 - "rev": "3e3f3c7f9977dc123c23ee21e8085ed63daf8c37", 225 - "type": "github" 226 - }, 227 - "original": { 228 - "owner": "nixos", 229 - "ref": "release-25.05", 230 - "repo": "nixpkgs", 231 - "type": "github" 232 124 } 233 125 }, 234 126 "provider": { ··· 261 153 }, 262 154 "root": { 263 155 "inputs": { 264 - "darwin": "darwin", 265 156 "den": "den", 266 157 "flake-aspects": "flake-aspects", 267 - "flake-file": "flake-file", 268 158 "flake-parts": "flake-parts", 269 159 "home-manager": "home-manager", 270 - "home-manager-stable": "home-manager-stable", 271 160 "import-tree": "import-tree", 272 - "neovim-nightly-overlay": "neovim-nightly-overlay", 273 - "nixos-wsl": "nixos-wsl", 161 + "nix-unit": "nix-unit", 274 162 "nixpkgs": "nixpkgs", 275 - "nixpkgs-lib": [ 276 - "nixpkgs" 277 - ], 278 - "nixpkgs-stable": "nixpkgs-stable", 279 - "provider": "provider", 280 - "systems": "systems" 281 - } 282 - }, 283 - "systems": { 284 - "locked": { 285 - "lastModified": 1681028828, 286 - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 287 - "owner": "nix-systems", 288 - "repo": "default", 289 - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 290 - "type": "github" 291 - }, 292 - "original": { 293 - "owner": "nix-systems", 294 - "repo": "default", 295 - "type": "github" 163 + "provider": "provider" 296 164 } 297 165 } 298 166 },
+21 -46
templates/ci/flake.nix
··· 1 - # DO-NOT-EDIT. This file was auto-generated using github:vic/flake-file. 2 - # Use `nix run .#write-flake` to regenerate it. 3 1 { 4 - 5 2 outputs = inputs: inputs.flake-parts.lib.mkFlake { inherit inputs; } (inputs.import-tree ./modules); 6 3 7 4 inputs = { 8 - darwin = { 9 - inputs.nixpkgs.follows = "nixpkgs"; 10 - url = "github:nix-darwin/nix-darwin"; 11 - }; 12 5 den.url = "github:vic/den"; 13 6 flake-aspects.url = "github:vic/flake-aspects"; 14 - flake-file.url = "github:vic/flake-file"; 15 - flake-parts = { 16 - inputs.nixpkgs-lib.follows = "nixpkgs-lib"; 17 - url = "github:hercules-ci/flake-parts"; 18 - }; 19 - home-manager = { 20 - inputs.nixpkgs.follows = "nixpkgs"; 21 - url = "github:nix-community/home-manager"; 22 - }; 23 - home-manager-stable = { 24 - inputs.nixpkgs.follows = "nixpkgs-stable"; 25 - url = "github:nix-community/home-manager/release-25.05"; 26 - }; 27 7 import-tree.url = "github:vic/import-tree"; 28 - neovim-nightly-overlay = { 29 - inputs = { 30 - flake-parts.follows = "flake-parts"; 31 - nixpkgs.follows = "nixpkgs"; 32 - }; 33 - url = "github:nix-community/neovim-nightly-overlay"; 8 + 9 + nixpkgs.url = "https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.xz"; 10 + flake-parts.url = "github:hercules-ci/flake-parts"; 11 + flake-parts.inputs.nixpkgs-lib.follows = "nixpkgs"; 12 + home-manager.url = "github:nix-community/home-manager"; 13 + home-manager.inputs = { 14 + nixpkgs.follows = "nixpkgs"; 34 15 }; 35 - nixos-wsl = { 36 - inputs = { 37 - flake-compat.follows = ""; 38 - nixpkgs.follows = "nixpkgs-stable"; 39 - }; 40 - url = "github:nix-community/nixos-wsl"; 16 + nix-unit.url = "github:nix-community/nix-unit"; 17 + nix-unit.inputs = { 18 + flake-parts.follows = "flake-parts"; 19 + nix-github-actions.follows = ""; 20 + nixpkgs.follows = "nixpkgs"; 21 + treefmt-nix.follows = ""; 41 22 }; 42 - nixpkgs.url = "https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.xz"; 43 - nixpkgs-lib.follows = "nixpkgs"; 44 - nixpkgs-stable.url = "github:nixos/nixpkgs/release-25.05"; 45 - provider = { 46 - inputs = { 47 - den.follows = "den"; 48 - flake-aspects.follows = "flake-aspects"; 49 - flake-parts.follows = "flake-parts"; 50 - import-tree.follows = "import-tree"; 51 - nixpkgs.follows = "nixpkgs"; 52 - }; 53 - url = "path:./provider"; 23 + 24 + provider.url = "path:./provider"; 25 + provider.inputs = { 26 + nixpkgs.follows = "nixpkgs"; 27 + flake-parts.follows = "flake-parts"; 28 + flake-aspects.follows = "flake-aspects"; 29 + import-tree.follows = "import-tree"; 30 + den.follows = "den"; 54 31 }; 55 - systems.url = "github:nix-systems/default"; 56 32 }; 57 - 58 33 }
-81
templates/ci/modules/angle-bracket-deep.nix
··· 1 - { 2 - inputs, 3 - lib, 4 - ns, 5 - # deadnix: skip 6 - __findFile ? __findFile, 7 - ... 8 - }: 9 - let 10 - treeModule.nixos.options.tree = lib.mkOption { 11 - type = lib.types.listOf lib.types.str; 12 - }; 13 - inputX = { 14 - denful.ns.root = { 15 - nixos.tree = [ "X-root" ]; 16 - provides.branch.nixos.tree = [ "X-branch" ]; 17 - provides.branch.provides.leaf.nixos.tree = [ "X-leaf" ]; 18 - }; 19 - }; 20 - inputY = { 21 - denful.ns.root = { 22 - nixos.tree = [ "Y-root" ]; 23 - provides.branch.nixos.tree = [ "Y-branch" ]; 24 - provides.branch.provides.leaf.nixos.tree = [ "Y-leaf" ]; 25 - }; 26 - }; 27 - in 28 - { 29 - 30 - imports = [ 31 - (inputs.den.namespace "ns" [ 32 - true 33 - inputX 34 - inputY 35 - ]) 36 - ]; 37 - 38 - ns.root = { 39 - nixos.tree = [ "local-root" ]; 40 - provides.branch.nixos.tree = [ "local-branch" ]; 41 - provides.branch.provides.leaf.nixos.tree = [ "local-leaf" ]; 42 - }; 43 - 44 - den.aspects.rockhopper.includes = [ 45 - treeModule 46 - <ns/root> 47 - <ns/root/branch> 48 - <ns/root/branch/leaf> 49 - ]; 50 - 51 - perSystem = 52 - { checkCond, rockhopper, ... }: 53 - let 54 - vals = lib.sort (a: b: a < b) rockhopper.config.tree; 55 - in 56 - { 57 - checks.ns-angle-bracket-root = checkCond "angle-bracket access root" (<ns/root> == ns.root); 58 - 59 - checks.ns-angle-bracket-branch = checkCond "angle-bracket access branch" ( 60 - <ns/root/branch> == ns.root._.branch 61 - ); 62 - 63 - checks.ns-angle-bracket-leaf = checkCond "angle-bracket access leaf" ( 64 - <ns/root/branch/leaf> == ns.root._.branch._.leaf 65 - ); 66 - 67 - checks.ns-tree-all-levels-merged = checkCond "all tree levels merged" ( 68 - vals == [ 69 - "X-branch" 70 - "X-leaf" 71 - "X-root" 72 - "Y-branch" 73 - "Y-leaf" 74 - "Y-root" 75 - "local-branch" 76 - "local-leaf" 77 - "local-root" 78 - ] 79 - ); 80 - }; 81 - }
-28
templates/ci/modules/auto-imported.nix
··· 1 - # configures class-automatic module auto imports for hosts/users/homes. 2 - # See documentation at modules/aspects/provides/import-tree.nix 3 - { 4 - # deadnix: skip 5 - __findFile ? __findFile, 6 - ... 7 - }: 8 - { 9 - 10 - # alice imports non-dendritic <class> modules from ../non-dendritic/alice/_<class>/*.nix 11 - den.aspects.alice.includes = [ (<den/import-tree> ./../non-dendritic/alice) ]; 12 - 13 - # See the documentation at batteries/import-tree.nix 14 - den.default.includes = [ 15 - (<den/import-tree/host> ./../non-dendritic/hosts) 16 - (<den/import-tree/user> ./../non-dendritic/users) 17 - (<den/import-tree/home> ./../non-dendritic/homes) 18 - ]; 19 - 20 - # tests 21 - perSystem = 22 - { checkCond, rockhopper, ... }: 23 - { 24 - checks.import-tree = checkCond "auto-imported from rockhopper/_nixos" ( 25 - rockhopper.config.auto-imported 26 - ); 27 - }; 28 - }
-76
templates/ci/modules/base-conf-modules.nix
··· 1 - # tests for extending `den.base.*` modules with capabilities (options). 2 - # these allow you to expend all hosts/users/homes with custom option 3 - # that can later be used by aspects for providing features. 4 - # 5 - { lib, ... }: 6 - { 7 - 8 - # This module is base for all host configs. 9 - den.base.host = 10 - { host, ... }: 11 - { 12 - options.capabilities.ssh-server = lib.mkEnableOption "Does host ${host.name} provide ssh?"; 13 - }; 14 - 15 - # This module is base for all user configs. 16 - den.base.user = 17 - { user, ... }: 18 - { 19 - options.isAdmin = lib.mkOption { 20 - type = lib.types.bool; 21 - default = user.name == "alice"; # only alice is always admin 22 - }; 23 - }; 24 - 25 - # This module is base for all home configs. 26 - # den.base.home = { home, ... }: { }; 27 - 28 - # This one is included on each host/user/home 29 - # it cannot access host/user/home values since this conf is generic. 30 - den.base.conf = { 31 - options.foo = lib.mkOption { 32 - type = lib.types.str; 33 - default = "bar"; 34 - }; 35 - }; 36 - 37 - # Now hosts and users can set any option defined in base modules. 38 - den.hosts.x86_64-linux.rockhopper = { 39 - capabilities.ssh-server = true; 40 - foo = "boo"; 41 - users.alice = { 42 - # isAdmin = true; # alice is admin by default, nothing explicit here. 43 - foo = "moo"; 44 - }; 45 - }; 46 - 47 - den.aspects.rockhopper.includes = 48 - let 49 - # An aspect can make use of these options to provide configuration. 50 - sshCapable = 51 - { host, ... }: 52 - { 53 - nixos.services.sshd.enable = host.capabilities.ssh-server; 54 - homeManager.services.ssh-agent.enable = host.capabilities.ssh-server; 55 - }; 56 - in 57 - [ sshCapable ]; 58 - 59 - # CI checks 60 - perSystem = 61 - { 62 - checkCond, 63 - rockhopper, 64 - alice-at-rockhopper, 65 - ... 66 - }: 67 - { 68 - checks.host-conf-rockhopper-sshd = checkCond "sshd enabled" ( 69 - rockhopper.config.services.sshd.enable == true 70 - ); 71 - checks.host-conf-alice-sshd = checkCond "ssh-agent enabled" ( 72 - alice-at-rockhopper.services.ssh-agent.enable == true 73 - ); 74 - }; 75 - 76 - }
-27
templates/ci/modules/builds.nix
··· 1 - # Adds some checks for CI 2 - { 3 - perSystem = 4 - { 5 - pkgs, 6 - checkFile, 7 - rockhopper, 8 - honeycrisp, 9 - cam, 10 - bob, 11 - ... 12 - }: 13 - let 14 - checks.x86_64-linux = { 15 - vm = checkFile "vm-builds" "${rockhopper.config.system.build.vm}/bin/run-rockhopper-vm"; 16 - hosts-rockhopper = checkFile "nixos-builds" rockhopper.config.system.build.toplevel; 17 - homes-cam = checkFile "home-builds" cam.activation-script; 18 - }; 19 - checks.aarch64-darwin = { 20 - hosts-honeycrisp = checkFile "darwin-builds" honeycrisp.config.system.build.toplevel; 21 - homes-bob = checkFile "darwin-home-builds" bob.activation-script; 22 - }; 23 - in 24 - { 25 - checks = checks.${pkgs.stdenv.hostPlatform.system} or { }; 26 - }; 27 - }
-67
templates/ci/modules/cross-flake-parametric.nix
··· 1 - { 2 - inputs, 3 - lib, 4 - provider, 5 - ... 6 - }: 7 - let 8 - providerModule.nixos.options.providerVars = lib.mkOption { 9 - type = lib.types.attrsOf lib.types.str; 10 - default = { }; 11 - }; 12 - in 13 - { 14 - flake-file.inputs.provider = { 15 - url = "path:./provider"; 16 - inputs.den.follows = "den"; 17 - inputs.flake-aspects.follows = "flake-aspects"; 18 - inputs.flake-parts.follows = "flake-parts"; 19 - inputs.import-tree.follows = "import-tree"; 20 - inputs.nixpkgs.follows = "nixpkgs"; 21 - }; 22 - 23 - imports = [ 24 - (inputs.den.namespace "provider" [ 25 - true 26 - inputs.provider 27 - ]) 28 - ]; 29 - 30 - provider.tools._.dev._.editors = { 31 - nixos.providerVars.LOCAL_EDITOR = "emacs"; 32 - }; 33 - 34 - den.aspects.rockhopper.includes = [ 35 - providerModule 36 - provider.tools._.dev._.editors 37 - provider.tools._.dev._.shells 38 - ]; 39 - 40 - perSystem = 41 - { checkCond, rockhopper, ... }: 42 - let 43 - vars = rockhopper.config.providerVars; 44 - env = rockhopper.config.environment.variables; 45 - in 46 - { 47 - checks.cross-flake-provider-editor = checkCond "provider editor var set" ( 48 - env.PROVIDER_EDITOR == "vim" 49 - ); 50 - 51 - checks.cross-flake-provider-shell = checkCond "provider shell var set" ( 52 - env.PROVIDER_SHELL == "fish" 53 - ); 54 - 55 - checks.cross-flake-local-editor = checkCond "local editor var set" (vars.LOCAL_EDITOR == "emacs"); 56 - 57 - checks.cross-flake-namespace-merged = checkCond "namespace merged from provider input" ( 58 - provider.tools._.dev._.editors == inputs.self.denful.provider.tools._.dev._.editors 59 - && provider.tools._.dev._.shells == inputs.self.denful.provider.tools._.dev._.shells 60 - ); 61 - 62 - checks.cross-flake-input-denful = checkCond "input provider denful accessible" ( 63 - inputs.provider.denful.provider.tools._.dev._.editors.description 64 - == "Editor configurations from provider flake" 65 - ); 66 - }; 67 - }
-30
templates/ci/modules/custom-home-managed-package.nix
··· 1 - { 2 - # Including an static aspect should not cause duplicate definitions 3 - den.aspects.alice.includes = [ 4 - { 5 - homeManager = 6 - { pkgs, ... }: 7 - { 8 - programs.emacs.enable = true; 9 - programs.emacs.package = pkgs.emacs30-nox; 10 - }; 11 - } 12 - ]; 13 - 14 - perSystem = 15 - { 16 - checkCond, 17 - alice-at-rockhopper, 18 - lib, 19 - ... 20 - }: 21 - { 22 - checks.alice-custom-emacs = checkCond "set uniquely via a static includes" ( 23 - let 24 - expr = lib.getName alice-at-rockhopper.programs.emacs.package; 25 - expected = "emacs-nox"; 26 - in 27 - expr == expected 28 - ); 29 - }; 30 - }
-35
templates/ci/modules/custom-nixos-module.nix
··· 1 - { lib, ... }: 2 - let 3 - # A custom `nixos` class module that defines an option `names`. 4 - # Used to test that we are not duplicating values from owned configs. 5 - nixosNames = names: { options.${names} = lib.mkOption { type = lib.types.listOf lib.types.str; }; }; 6 - in 7 - { 8 - den.default.nixos.imports = [ (nixosNames "people") ]; 9 - den.default.includes = [ 10 - ( 11 - { user, ... }: 12 - { 13 - nixos.people = [ user.name ]; 14 - } 15 - ) 16 - ]; 17 - 18 - den.aspects.rockhopper.includes = [ 19 - # Example: importing a third-party nixos module. 20 - { nixos.imports = [ (nixosNames "names") ]; } 21 - ]; 22 - 23 - den.aspects.rockhopper.nixos.names = [ "tux" ]; 24 - 25 - perSystem = 26 - { checkCond, rockhopper, ... }: 27 - { 28 - checks.rockhopper-default-people = checkCond "set from den.default for each user" ( 29 - rockhopper.config.people == [ "alice" ] 30 - ); 31 - checks.rockhopper-names-single-entry = checkCond "custom nixos array option set once" ( 32 - rockhopper.config.names == [ "tux" ] 33 - ); 34 - }; 35 - }
-78
templates/ci/modules/deep-nested-namespace.nix
··· 1 - { 2 - inputs, 3 - lib, 4 - deep, 5 - ... 6 - }: 7 - let 8 - deepModule.nixos.options.deepVals = lib.mkOption { 9 - type = lib.types.listOf lib.types.str; 10 - }; 11 - depthA = { 12 - denful.deep.a._.b._.c._.d._.e = { 13 - description = "5 levels deep from inputA"; 14 - nixos.deepVals = [ "inputA-5-levels" ]; 15 - provides.f.nixos.deepVals = [ "inputA-6-levels" ]; 16 - }; 17 - }; 18 - depthB = { 19 - denful.deep.a._.b._.c._.d._.e = { 20 - nixos.deepVals = [ "inputB-5-levels" ]; 21 - provides.f.nixos.deepVals = [ "inputB-6-levels" ]; 22 - }; 23 - }; 24 - in 25 - { 26 - imports = [ 27 - (inputs.den.namespace "deep" [ 28 - true 29 - depthA 30 - depthB 31 - ]) 32 - ]; 33 - 34 - deep.a._.b._.c._.d._.e = { 35 - nixos.deepVals = [ "local-5-levels" ]; 36 - provides.f.nixos.deepVals = [ "local-6-levels" ]; 37 - }; 38 - 39 - den.aspects.rockhopper.includes = [ 40 - deepModule 41 - deep.a._.b._.c._.d._.e 42 - deep.a._.b._.c._.d._.e._.f 43 - ]; 44 - 45 - perSystem = 46 - { checkCond, rockhopper, ... }: 47 - let 48 - vals = lib.sort (a: b: a < b) rockhopper.config.deepVals; 49 - in 50 - { 51 - checks.deep-nest-5-levels = checkCond "5 levels deep merged correctly" ( 52 - builtins.elem "inputA-5-levels" vals 53 - && builtins.elem "inputB-5-levels" vals 54 - && builtins.elem "local-5-levels" vals 55 - ); 56 - 57 - checks.deep-nest-6-levels = checkCond "6 levels deep merged correctly" ( 58 - builtins.elem "inputA-6-levels" vals 59 - && builtins.elem "inputB-6-levels" vals 60 - && builtins.elem "local-6-levels" vals 61 - ); 62 - 63 - checks.deep-nest-all-merged = checkCond "all values merged" ( 64 - vals == [ 65 - "inputA-5-levels" 66 - "inputA-6-levels" 67 - "inputB-5-levels" 68 - "inputB-6-levels" 69 - "local-5-levels" 70 - "local-6-levels" 71 - ] 72 - ); 73 - 74 - checks.deep-nest-flake-output = checkCond "deep namespace as flake output" ( 75 - inputs.self.denful.deep.a._.b._.c._.d._.e._.f == deep.a._.b._.c._.d._.e._.f 76 - ); 77 - }; 78 - }
-14
templates/ci/modules/defaults.nix
··· 1 - # User TODO: Remove this file. 2 - { 3 - # default aspect can be used for global static settings. 4 - den.default = { 5 - # static values. 6 - darwin.system.stateVersion = 6; 7 - nixos.system.stateVersion = "25.05"; 8 - homeManager.home.stateVersion = "25.05"; 9 - 10 - # these defaults are set for checking with CI. 11 - nixos.programs.vim.enable = true; 12 - darwin.programs.zsh.enable = true; 13 - }; 14 - }
-27
templates/ci/modules/define-user.nix
··· 1 - { den, ... }: 2 - { 3 - den.default.includes = [ 4 - # Example: parametric over many contexts: { home }, { host, user }, { fromUser, toHost } 5 - den.provides.define-user 6 - ]; 7 - 8 - perSystem = 9 - { 10 - checkCond, 11 - rockhopper, 12 - adelie, 13 - ... 14 - }: 15 - { 16 - 17 - checks.alice-exists-on-rockhopper = checkCond "den.default.user.includes defines user on host" ( 18 - rockhopper.config.users.users.alice.isNormalUser 19 - ); 20 - checks.alice-not-exists-on-adelie = checkCond "den.default.user.includes defines user on host" ( 21 - !adelie.config.users.users ? alice 22 - ); 23 - checks.will-exists-on-adelie = checkCond "den.default.user.includes defines user on host" ( 24 - adelie.config.users.users.will.isNormalUser 25 - ); 26 - }; 27 - }
-9
templates/ci/modules/dendritic.nix
··· 1 - { inputs, lib, ... }: 2 - { 3 - flake-file.inputs.flake-file.url = lib.mkDefault "github:vic/flake-file"; 4 - flake-file.inputs.den.url = lib.mkDefault "github:vic/den"; 5 - imports = [ 6 - (inputs.flake-file.flakeModules.dendritic or { }) 7 - (inputs.den.flakeModules.dendritic or { }) 8 - ]; 9 - }
+13
templates/ci/modules/empty.nix
··· 1 + # Copy this file to start new tests 2 + { denTest, ... }: 3 + { 4 + flake.tests.empty = { 5 + test-no-aspects = denTest ( 6 + { den, ... }: 7 + { 8 + expr = den.aspects; 9 + expected = { }; 10 + } 11 + ); 12 + }; 13 + }
-8
templates/ci/modules/enable-wsl-host.nix
··· 1 - { inputs, ... }: 2 - { 3 - # Example: adelie host using github:nix-community/NixOS-WSL 4 - den.aspects.adelie.nixos = { 5 - imports = [ inputs.nixos-wsl.nixosModules.default ]; 6 - wsl.enable = true; 7 - }; 8 - }
+100
templates/ci/modules/features/angle-brackets.nix
··· 1 + { denTest, inputs, ... }: 2 + { 3 + 4 + flake.tests.angle-brackets = { 5 + 6 + test-den-dot-access = denTest ( 7 + { den, __findFile, ... }: 8 + { 9 + _module.args.__findFile = den.lib.__findFile; 10 + expr = <den.lib> ? owned; 11 + expected = true; 12 + } 13 + ); 14 + 15 + test-den-slash-provides = denTest ( 16 + { 17 + den, 18 + __findFile, 19 + lib, 20 + ... 21 + }: 22 + { 23 + _module.args.__findFile = den.lib.__findFile; 24 + expr = lib.isFunction <den/import-tree/host>; 25 + expected = true; 26 + } 27 + ); 28 + 29 + test-aspect-without-prefix = denTest ( 30 + { 31 + den, 32 + __findFile, 33 + lib, 34 + ... 35 + }: 36 + { 37 + _module.args.__findFile = den.lib.__findFile; 38 + den.hosts.x86_64-linux.igloo.users.tux = { }; 39 + den.aspects.igloo = { }; 40 + expr = <igloo> ? provides; 41 + expected = true; 42 + } 43 + ); 44 + 45 + test-aspect-provides = denTest ( 46 + { 47 + den, 48 + __findFile, 49 + lib, 50 + ... 51 + }: 52 + { 53 + _module.args.__findFile = den.lib.__findFile; 54 + den.aspects.foo.provides.bar.nixos = { }; 55 + expr = <foo/bar> ? nixos; 56 + expected = true; 57 + } 58 + ); 59 + 60 + test-namespace-access = denTest ( 61 + { 62 + den, 63 + __findFile, 64 + ns, 65 + ... 66 + }: 67 + { 68 + _module.args.__findFile = den.lib.__findFile; 69 + 70 + imports = [ (inputs.den.namespace "ns" true) ]; 71 + 72 + ns.moo.silly = true; 73 + 74 + expr = <ns/moo> ? silly; 75 + expected = true; 76 + } 77 + ); 78 + 79 + test-deep-nested-provides = denTest ( 80 + { 81 + den, 82 + __findFile, 83 + igloo, 84 + ... 85 + }: 86 + { 87 + _module.args.__findFile = den.lib.__findFile; 88 + 89 + den.hosts.x86_64-linux.igloo.users.tux = { }; 90 + den.aspects.foo.provides.bar.provides.baz.nixos.programs.fish.enable = true; 91 + den.aspects.igloo.includes = [ <foo/bar/baz> ]; 92 + 93 + expr = igloo.programs.fish.enable; 94 + expected = true; 95 + } 96 + ); 97 + 98 + }; 99 + 100 + }
+49
templates/ci/modules/features/batteries/define-user.nix
··· 1 + { denTest, ... }: 2 + { 3 + 4 + flake.tests.define-user.test-on-nixos-included-at-user = denTest ( 5 + { 6 + den, 7 + lib, 8 + igloo, 9 + ... 10 + }: 11 + { 12 + den.hosts.x86_64-linux.igloo.users.tux = { }; 13 + den.aspects.tux.includes = [ den._.define-user ]; 14 + expr = igloo.users.users.tux.isNormalUser; 15 + expected = true; 16 + } 17 + ); 18 + 19 + flake.tests.define-user.test-on-nixos-included-at-host = denTest ( 20 + { 21 + den, 22 + lib, 23 + igloo, 24 + ... 25 + }: 26 + { 27 + den.hosts.x86_64-linux.igloo.users.tux = { }; 28 + den.aspects.igloo.includes = [ den._.define-user ]; 29 + expr = igloo.users.users.tux.isNormalUser; 30 + expected = true; 31 + } 32 + ); 33 + 34 + flake.tests.define-user.test-on-nixos-included-at-default = denTest ( 35 + { 36 + den, 37 + lib, 38 + igloo, 39 + ... 40 + }: 41 + { 42 + den.hosts.x86_64-linux.igloo.users.tux = { }; 43 + den.default.includes = [ den._.define-user ]; 44 + expr = igloo.users.users.tux.isNormalUser; 45 + expected = true; 46 + } 47 + ); 48 + 49 + }
+50
templates/ci/modules/features/batteries/flake-parts.nix
··· 1 + { denTest, inputs, ... }: 2 + { 3 + 4 + flake.tests.flake-parts.inputs' = denTest ( 5 + { 6 + den, 7 + lib, 8 + igloo, 9 + ... 10 + }: 11 + { 12 + den.hosts.x86_64-linux.igloo.users.tux = { }; 13 + den.default.homeManager.home.stateVersion = "25.11"; 14 + 15 + den.default.includes = [ den._.inputs' ]; 16 + den.aspects.igloo.nixos = 17 + { inputs', ... }: 18 + { 19 + environment.systemPackages = [ inputs'.nixpkgs.legacyPackages.hello ]; 20 + }; 21 + 22 + expr = builtins.elem "hello" (map lib.getName igloo.environment.systemPackages); 23 + expected = true; 24 + } 25 + ); 26 + 27 + flake.tests.flake-parts.self' = denTest ( 28 + { 29 + den, 30 + lib, 31 + igloo, 32 + ... 33 + }: 34 + { 35 + den.hosts.x86_64-linux.igloo.users.tux = { }; 36 + den.default.homeManager.home.stateVersion = "25.11"; 37 + 38 + den.default.includes = [ den._.self' ]; 39 + den.aspects.igloo.nixos = 40 + { self', ... }: 41 + { 42 + environment.systemPackages = [ self'.packages.hello ]; 43 + }; 44 + 45 + expr = builtins.elem "hello" (map lib.getName igloo.environment.systemPackages); 46 + expected = true; 47 + } 48 + ); 49 + 50 + }
+32
templates/ci/modules/features/batteries/import-tree.nix
··· 1 + { denTest, ... }: 2 + { 3 + flake.tests.import-tree = { 4 + 5 + test-host-auto-import = denTest ( 6 + { den, config, ... }: 7 + { 8 + den.hosts.x86_64-linux.rockhopper.users.tux = { }; 9 + den.default.includes = [ 10 + (den._.import-tree._.host ../../../non-dendritic/hosts) 11 + ]; 12 + 13 + expr = config.flake.nixosConfigurations.rockhopper.config.auto-imported; 14 + expected = true; 15 + } 16 + ); 17 + 18 + test-no-import-for-missing-dir = denTest ( 19 + { den, igloo, ... }: 20 + { 21 + den.hosts.x86_64-linux.igloo.users.tux = { }; 22 + den.aspects.igloo.includes = [ 23 + (den._.import-tree ../../../non-dendritic/no-such-dir) 24 + ]; 25 + 26 + expr = igloo ? auto-imported; 27 + expected = false; 28 + } 29 + ); 30 + 31 + }; 32 + }
+22
templates/ci/modules/features/batteries/primary-user.nix
··· 1 + { denTest, ... }: 2 + { 3 + 4 + flake.tests.primary-user.test-on-nixos-included-at-user = denTest ( 5 + { 6 + den, 7 + lib, 8 + igloo, 9 + ... 10 + }: 11 + { 12 + den.hosts.x86_64-linux.igloo.users.tux = { }; 13 + den.aspects.tux.includes = [ den._.primary-user ]; 14 + expr = igloo.users.users.tux.extraGroups; 15 + expected = [ 16 + "wheel" 17 + "networkmanager" 18 + ]; 19 + } 20 + ); 21 + 22 + }
+27
templates/ci/modules/features/batteries/tty-autologin.nix
··· 1 + { denTest, ... }: 2 + { 3 + flake.tests.tty-autologin = { 4 + 5 + test-service-defined = denTest ( 6 + { den, config, ... }: 7 + { 8 + den.hosts.x86_64-linux.igloo = { }; 9 + den.aspects.igloo.includes = [ (den._.tty-autologin "root") ]; 10 + 11 + expr = config.flake.nixosConfigurations.igloo.config.systemd.services ? "getty@tty1"; 12 + expected = true; 13 + } 14 + ); 15 + 16 + test-no-service-without-include = denTest ( 17 + { den, config, ... }: 18 + { 19 + den.hosts.x86_64-linux.igloo = { }; 20 + 21 + expr = config.flake.nixosConfigurations.igloo.config.systemd.services ? "getty@tty1"; 22 + expected = false; 23 + } 24 + ); 25 + 26 + }; 27 + }
+28
templates/ci/modules/features/batteries/unfree.nix
··· 1 + { denTest, ... }: 2 + { 3 + flake.tests.unfree = { 4 + 5 + test-packages-set-on-nixos = denTest ( 6 + { den, igloo, ... }: 7 + { 8 + den.hosts.x86_64-linux.igloo.users.tux = { }; 9 + den.aspects.igloo.includes = [ (den._.unfree [ "discord" ]) ]; 10 + expr = igloo.nixpkgs.config.allowUnfreePredicate { pname = "discord"; }; 11 + expected = true; 12 + } 13 + ); 14 + 15 + test-packages-set-on-home-manager = denTest ( 16 + { den, tuxHm, ... }: 17 + { 18 + den.hosts.x86_64-linux.igloo.users.tux = { }; 19 + den.default.homeManager.home.stateVersion = "25.11"; 20 + den.aspects.tux.includes = [ (den._.unfree [ "vscode" ]) ]; 21 + 22 + expr = tuxHm.nixpkgs.config.allowUnfreePredicate { pname = "vscode"; }; 23 + expected = true; 24 + } 25 + ); 26 + 27 + }; 28 + }
+29
templates/ci/modules/features/batteries/user-shell.nix
··· 1 + { denTest, ... }: 2 + { 3 + 4 + flake.tests.user-shell.test-on-nixos-included-at-user = denTest ( 5 + { 6 + den, 7 + lib, 8 + igloo, 9 + tuxHm, 10 + ... 11 + }: 12 + { 13 + den.hosts.x86_64-linux.igloo.users.tux = { }; 14 + den.default.homeManager.home.stateVersion = "25.11"; 15 + den.aspects.tux.includes = [ (den._.user-shell "fish") ]; 16 + expr = { 17 + defaultShell = igloo.users.users.tux.shell.pname; 18 + osFish = igloo.programs.fish.enable; 19 + hmFish = tuxHm.programs.fish.enable; 20 + }; 21 + expected = { 22 + defaultShell = "fish"; 23 + osFish = true; 24 + hmFish = true; 25 + }; 26 + } 27 + ); 28 + 29 + }
+118
templates/ci/modules/features/conditional-config.nix
··· 1 + { denTest, ... }: 2 + { 3 + flake.tests.conditional-config = { 4 + 5 + test-conditional-hm-by-user-and-host = denTest ( 6 + { 7 + den, 8 + lib, 9 + tuxHm, 10 + pinguHm, 11 + ... 12 + }: 13 + let 14 + git-for-linux-only = 15 + { user, host, ... }: 16 + if user.userName == "tux" && !lib.hasSuffix "darwin" host.system then 17 + { homeManager.programs.git.enable = true; } 18 + else 19 + { }; 20 + in 21 + { 22 + den.hosts.x86_64-linux.igloo.users = { 23 + tux = { }; 24 + pingu = { }; 25 + }; 26 + den.default.homeManager.home.stateVersion = "25.11"; 27 + den.aspects.tux.includes = [ git-for-linux-only ]; 28 + 29 + expr = [ 30 + tuxHm.programs.git.enable 31 + pinguHm.programs.git.enable 32 + ]; 33 + expected = [ 34 + true 35 + false 36 + ]; 37 + } 38 + ); 39 + 40 + test-conditional-os-by-user-system = denTest ( 41 + { 42 + den, 43 + lib, 44 + igloo, 45 + iceberg, 46 + ... 47 + }: 48 + let 49 + tmux-on-linux = 50 + { user, host, ... }: 51 + if user.userName == "tux" && !lib.hasSuffix "darwin" host.system then 52 + { nixos.programs.tmux.enable = true; } 53 + else 54 + { }; 55 + in 56 + { 57 + den.hosts.x86_64-linux.igloo.users.tux = { }; 58 + den.hosts.x86_64-linux.iceberg.users.tux = { }; 59 + den.aspects.tux.includes = [ tmux-on-linux ]; 60 + 61 + expr = [ 62 + igloo.programs.tmux.enable 63 + iceberg.programs.tmux.enable 64 + ]; 65 + expected = [ 66 + true 67 + true 68 + ]; 69 + } 70 + ); 71 + 72 + test-custom-nixos-module-import = denTest ( 73 + { 74 + den, 75 + lib, 76 + igloo, 77 + ... 78 + }: 79 + let 80 + peopleModule = { 81 + options.people = lib.mkOption { type = lib.types.listOf lib.types.str; }; 82 + }; 83 + in 84 + { 85 + den.hosts.x86_64-linux.igloo.users.tux = { }; 86 + den.default.nixos.imports = [ peopleModule ]; 87 + den.default.includes = [ 88 + ( 89 + { user, ... }: 90 + { 91 + nixos.people = [ user.userName ]; 92 + } 93 + ) 94 + ]; 95 + 96 + expr = igloo.people; 97 + expected = [ "tux" ]; 98 + } 99 + ); 100 + 101 + test-static-aspect-in-default = denTest ( 102 + { den, igloo, ... }: 103 + let 104 + set-timezone = { 105 + nixos.time.timeZone = "UTC"; 106 + }; 107 + in 108 + { 109 + den.hosts.x86_64-linux.igloo.users.tux = { }; 110 + den.default.includes = [ set-timezone ]; 111 + 112 + expr = igloo.time.timeZone; 113 + expected = "UTC"; 114 + } 115 + ); 116 + 117 + }; 118 + }
+57
templates/ci/modules/features/context/apply-non-exact.nix
··· 1 + { denTest, ... }: 2 + { 3 + flake.tests.ctx-non-exact.test-apply-non-exact-less = denTest ( 4 + { den, funnyNames, ... }: 5 + { 6 + den.ctx.foobar.desc = "{foo,bar} context"; 7 + den.ctx.foobar.conf = 8 + # use atLeast if you get error: function called with unexpected argument 9 + den.lib.take.atLeast ( 10 + { foo, bar }: 11 + { 12 + funny.names = [ 13 + foo 14 + bar 15 + ]; 16 + } 17 + ); 18 + 19 + expr = funnyNames ( 20 + den.ctx.foobar { 21 + foo = "moo"; 22 + # missing bar 23 + } 24 + ); 25 + 26 + expected = [ ]; 27 + } 28 + ); 29 + 30 + flake.tests.ctx-non-exact.test-apply-non-exact-more = denTest ( 31 + { den, funnyNames, ... }: 32 + { 33 + den.ctx.foobar.desc = "{foo,bar} context"; 34 + den.ctx.foobar.conf = 35 + # use exactly if you want to restrict to not having more args 36 + den.lib.take.exactly ( 37 + { foo, bar }: 38 + { 39 + funny.names = [ 40 + foo 41 + bar 42 + ]; 43 + } 44 + ); 45 + 46 + expr = funnyNames ( 47 + den.ctx.foobar { 48 + foo = "moo"; 49 + bar = "bar"; 50 + baz = "man"; 51 + } 52 + ); 53 + 54 + expected = [ ]; 55 + } 56 + ); 57 + }
+32
templates/ci/modules/features/context/apply.nix
··· 1 + { denTest, ... }: 2 + { 3 + flake.tests.ctx.test-apply = denTest ( 4 + { den, funnyNames, ... }: 5 + { 6 + den.ctx.foobar.desc = "{foo,bar} context"; 7 + den.ctx.foobar.conf = 8 + { foo, bar }: 9 + { 10 + funny.names = [ 11 + foo 12 + bar 13 + ]; 14 + }; 15 + 16 + den.ctx.foobar.funny.names = [ "owned" ]; 17 + 18 + expr = funnyNames ( 19 + den.ctx.foobar { 20 + foo = "moo"; 21 + bar = "baa"; 22 + } 23 + ); 24 + 25 + expected = [ 26 + "baa" 27 + "moo" 28 + "owned" 29 + ]; 30 + } 31 + ); 32 + }
+83
templates/ci/modules/features/context/custom-ctx.nix
··· 1 + { denTest, ... }: 2 + { 3 + flake.tests.ctx-custom = { 4 + 5 + test-ctx-into = denTest ( 6 + { 7 + den, 8 + lib, 9 + funnyNames, 10 + ... 11 + }: 12 + { 13 + den.ctx.greeting.desc = "{hello} context"; 14 + den.ctx.greeting.conf = 15 + { hello }: 16 + { 17 + funny.names = [ hello ]; 18 + }; 19 + den.ctx.greeting.into.shout = { hello }: [ { shout = lib.toUpper hello; } ]; 20 + 21 + den.ctx.shout.conf = 22 + { shout }: 23 + { 24 + funny.names = [ shout ]; 25 + }; 26 + 27 + expr = funnyNames (den.ctx.greeting { hello = "world"; }); 28 + expected = [ 29 + "WORLD" 30 + "world" 31 + ]; 32 + } 33 + ); 34 + 35 + test-ctx-includes-static-and-parametric = denTest ( 36 + { den, funnyNames, ... }: 37 + { 38 + den.ctx.foo.desc = "{foo} context"; 39 + den.ctx.foo.conf = 40 + { foo }: 41 + { 42 + funny.names = [ foo ]; 43 + }; 44 + den.ctx.foo.includes = [ 45 + { funny.names = [ "static-include" ]; } 46 + ( 47 + { foo, ... }: 48 + { 49 + funny.names = [ "param-${foo}" ]; 50 + } 51 + ) 52 + ]; 53 + 54 + expr = funnyNames (den.ctx.foo { foo = "hello"; }); 55 + expected = [ 56 + "hello" 57 + "param-hello" 58 + "static-include" 59 + ]; 60 + } 61 + ); 62 + 63 + test-ctx-owned = denTest ( 64 + { den, funnyNames, ... }: 65 + { 66 + den.ctx.bar.desc = "{x} context"; 67 + den.ctx.bar.conf = 68 + { x }: 69 + { 70 + funny.names = [ x ]; 71 + }; 72 + den.ctx.bar.funny.names = [ "owned" ]; 73 + 74 + expr = funnyNames (den.ctx.bar { x = "val"; }); 75 + expected = [ 76 + "owned" 77 + "val" 78 + ]; 79 + } 80 + ); 81 + 82 + }; 83 + }
+67
templates/ci/modules/features/context/den-default.nix
··· 1 + { denTest, ... }: 2 + { 3 + 4 + flake.tests.den-default.test-includes-owned = denTest ( 5 + { 6 + den, 7 + lib, 8 + igloo, 9 + ... 10 + }: 11 + { 12 + den.hosts.x86_64-linux.igloo.users.tux = { }; 13 + 14 + den.default.includes = [ den.aspects.foo ]; 15 + den.aspects.foo.nixos.users.users.tux.description = "pingu"; 16 + 17 + expr = igloo.users.users.tux.description; 18 + expected = "pingu"; 19 + } 20 + ); 21 + 22 + flake.tests.den-default.test-includes-host-function = denTest ( 23 + { 24 + den, 25 + lib, 26 + igloo, 27 + ... 28 + }: 29 + { 30 + den.hosts.x86_64-linux.igloo.users.tux = { }; 31 + 32 + den.default.includes = [ den.aspects.foo ]; 33 + den.aspects.foo = 34 + { host, ... }: 35 + { 36 + nixos.users.users.tux.description = "pingu"; 37 + }; 38 + 39 + expr = igloo.users.users.tux.description; 40 + expected = "pingu"; 41 + } 42 + ); 43 + 44 + flake.tests.den-default.test-includes-user-function = denTest ( 45 + { 46 + den, 47 + lib, 48 + igloo, 49 + ... 50 + }: 51 + { 52 + den.hosts.x86_64-linux.igloo.users.tux.userName = "pingu"; 53 + 54 + den.default.includes = [ den.aspects.foo ]; 55 + 56 + den.aspects.foo = 57 + { user, ... }: 58 + { 59 + nixos.users.users.tux.description = user.userName; 60 + }; 61 + 62 + expr = igloo.users.users.tux.description; 63 + expected = "pingu"; 64 + } 65 + ); 66 + 67 + }
+203
templates/ci/modules/features/context/host-propagation.nix
··· 1 + { denTest, ... }: 2 + { 3 + 4 + # This test uses the `funny.names` test option to 5 + # demostrate different places and context-aspects that 6 + # can contribute configurations to the host. 7 + # 8 + # Note that both host and user aspects include default 9 + # and because of that, default owned and static values 10 + # might be duplicated. This is why users are NOT adviced 11 + # to abuse den.default. 12 + # 13 + # The behaviour is correct, but using den.default for 14 + # everything without care will cause deplication problems. 15 + # Instead, users should include either directly on the host 16 + # or by using `den.ctx.host` or `den.ctx.user`. 17 + flake.tests.ctx-transformation.test-host = denTest ( 18 + { 19 + den, 20 + lib, 21 + show, 22 + funnyNames, 23 + ... 24 + }: 25 + let 26 + inherit (den.lib) parametric take; 27 + 28 + keys = ctx: "{${builtins.concatStringsSep "," (builtins.attrNames ctx)}}"; 29 + in 30 + { 31 + 32 + den.hosts.x86_64-linux.igloo.users.tux = { }; 33 + 34 + den.aspects.igloo.funny.names = [ "host-owned" ]; 35 + den.aspects.igloo.includes = [ 36 + { funny.names = [ "host-static" ]; } 37 + 38 + ( 39 + { host, ... }@ctx: 40 + { 41 + funny.names = [ "host-lax ${keys ctx}" ]; 42 + } 43 + ) 44 + (take.exactly ( 45 + { host }: 46 + { 47 + funny.names = [ "host-exact" ]; 48 + } 49 + )) 50 + (take.atLeast ( 51 + { host, never }: 52 + { 53 + funny.names = [ "host-never" ]; 54 + } 55 + )) 56 + 57 + ( 58 + { host, user, ... }@ctx: 59 + { 60 + funny.names = [ "host+user-lax ${keys ctx}" ]; 61 + } 62 + ) 63 + (take.exactly ( 64 + { host, user }: 65 + { 66 + funny.names = [ "host+user-exact" ]; 67 + } 68 + )) 69 + (take.atLeast ( 70 + { 71 + host, 72 + user, 73 + never, 74 + }: 75 + { 76 + funny.names = [ "host+user-never" ]; 77 + } 78 + )) 79 + ]; 80 + 81 + den.aspects.tux.funny.names = [ "user-owned" ]; 82 + den.aspects.tux.includes = [ 83 + { funny.names = [ "user-static" ]; } 84 + 85 + ( 86 + { user, ... }@ctx: 87 + { 88 + funny.names = [ "user-lax ${keys ctx}" ]; 89 + } 90 + ) 91 + (take.exactly ( 92 + { host, user }: 93 + { 94 + funny.names = [ "user-exact" ]; 95 + } 96 + )) 97 + (take.atLeast ( 98 + { 99 + host, 100 + user, 101 + never, 102 + }: 103 + { 104 + funny.names = [ "user-never" ]; 105 + } 106 + )) 107 + ]; 108 + 109 + den.ctx.hm-host.funny.names = [ "hm-host detected" ]; 110 + den.ctx.hm-host.includes = [ 111 + ( 112 + { host, ... }@ctx: 113 + { 114 + funny.names = [ "hm-host host-lax ${keys ctx}" ]; 115 + } 116 + ) 117 + ]; 118 + 119 + den.ctx.hm-user.includes = [ 120 + ( 121 + { host, user, ... }@ctx: 122 + { 123 + funny.names = [ "hm-user lax ${keys ctx}" ]; 124 + } 125 + ) 126 + ]; 127 + 128 + den.default.funny.names = [ "default-owned" ]; 129 + den.default.includes = [ 130 + { funny.names = [ "default-static" ]; } 131 + (ctx: { funny.names = [ "default-anyctx ${keys ctx}" ]; }) 132 + 133 + ( 134 + { host, ... }@ctx: 135 + { 136 + funny.names = [ "default-host-lax ${keys ctx}" ]; 137 + } 138 + ) 139 + ( 140 + { user, ... }@ctx: 141 + { 142 + funny.names = [ "default-user-lax ${keys ctx}" ]; 143 + } 144 + ) 145 + ( 146 + { host, user, ... }@ctx: 147 + { 148 + funny.names = [ "default-host+user-lax ${keys ctx}" ]; 149 + } 150 + ) 151 + 152 + # the following error means an aspect is not parametric but static. (document this) 153 + # > error: function 'anonymous lambda' called without required argument 'user' 154 + ]; 155 + 156 + expr = funnyNames ( 157 + den.ctx.host { 158 + host = den.hosts.x86_64-linux.igloo; 159 + } 160 + ); 161 + 162 + expected = [ 163 + "default-anyctx {aspect-chain,class}" 164 + "default-anyctx {aspect-chain,class}" 165 + "default-anyctx {host,user}" 166 + "default-anyctx {host}" 167 + 168 + "default-host+user-lax {host,user}" 169 + "default-host-lax {host,user}" 170 + "default-host-lax {host}" 171 + 172 + "default-owned" 173 + "default-owned" 174 + 175 + "default-static" 176 + "default-static" 177 + 178 + "default-user-lax {host,user}" 179 + 180 + "hm-host detected" 181 + "hm-host host-lax {host}" 182 + "hm-user lax {host,user}" 183 + 184 + "host+user-exact" 185 + "host+user-lax {host,user}" 186 + 187 + "host-exact" 188 + "host-lax {host,user}" 189 + "host-lax {host}" 190 + 191 + "host-owned" 192 + "host-static" 193 + 194 + "user-exact" 195 + "user-lax {host,user}" 196 + "user-owned" 197 + "user-static" 198 + ]; 199 + 200 + } 201 + ); 202 + 203 + }
+29
templates/ci/modules/features/deadbugs/_external-namespace-deep-aspect.nix
··· 1 + { denTest, inputs, ... }: 2 + { 3 + 4 + flake.tests.deadbugs.namespace-deep-aspect = { 5 + 6 + test-external-flake = denTest ( 7 + { 8 + den, 9 + provider, 10 + igloo, 11 + ... 12 + }: 13 + { 14 + imports = [ 15 + (inputs.den.namespace "provider" [ 16 + true 17 + inputs.provider 18 + ]) 19 + ]; 20 + den.hosts.x86_64-linux.igloo.users.tux = { }; 21 + den.aspects.igloo.includes = [ provider.tools._.dev._.editors ]; 22 + expr = igloo.programs.vim.enable; 23 + expected = true; 24 + } 25 + ); 26 + 27 + }; 28 + 29 + }
+89
templates/ci/modules/features/deadbugs/static-include-dup-package.nix
··· 1 + { denTest, ... }: 2 + { 3 + 4 + flake.tests.deadbugs.dups.test-static-include = denTest ( 5 + { 6 + den, 7 + lib, 8 + tuxHm, 9 + ... 10 + }: 11 + { 12 + den.default.homeManager.home.stateVersion = "25.11"; 13 + 14 + den.hosts.x86_64-linux.igloo.users.tux = { }; 15 + 16 + den.aspects.tux.includes = [ 17 + { 18 + homeManager = 19 + { pkgs, ... }: 20 + { 21 + programs.emacs.enable = true; 22 + programs.emacs.package = pkgs.emacs-nox; 23 + }; 24 + } 25 + ]; 26 + 27 + expr = lib.getName tuxHm.programs.emacs.package; 28 + expected = "emacs-nox"; 29 + } 30 + ); 31 + 32 + flake.tests.deadbugs.dups.test-default-func-include = denTest ( 33 + { 34 + den, 35 + lib, 36 + igloo, 37 + ... 38 + }: 39 + { 40 + den.default.homeManager.home.stateVersion = "25.11"; 41 + 42 + den.hosts.x86_64-linux.igloo.users.tux = { }; 43 + 44 + den.default.nixos.imports = [ 45 + { options.foo = lib.mkOption { type = lib.types.listOf lib.types.str; }; } 46 + ]; 47 + 48 + den.default.includes = [ 49 + ( 50 + { user, ... }: 51 + { 52 + nixos.foo = [ user.name ]; 53 + } 54 + ) 55 + ]; 56 + 57 + expr = igloo.foo; 58 + expected = [ "tux" ]; 59 + } 60 + ); 61 + 62 + flake.tests.deadbugs.dups.test-host-owned = denTest ( 63 + { 64 + den, 65 + lib, 66 + igloo, 67 + ... 68 + }: 69 + { 70 + den.default.homeManager.home.stateVersion = "25.11"; 71 + 72 + den.hosts.x86_64-linux.igloo.users.tux = { }; 73 + 74 + den.aspects.igloo.includes = [ 75 + { 76 + nixos.imports = [ 77 + { options.foo = lib.mkOption { type = lib.types.listOf lib.types.str; }; } 78 + ]; 79 + } 80 + ]; 81 + 82 + den.aspects.igloo.nixos.foo = [ "bar" ]; 83 + 84 + expr = igloo.foo; 85 + expected = [ "bar" ]; 86 + } 87 + ); 88 + 89 + }
+68
templates/ci/modules/features/default-includes.nix
··· 1 + { denTest, ... }: 2 + { 3 + flake.tests.default-includes = { 4 + 5 + test-set-hostname-from-host-context = denTest ( 6 + { den, igloo, ... }: 7 + { 8 + den.hosts.x86_64-linux.igloo.users.tux = { }; 9 + den.default.includes = [ 10 + ( 11 + { host, ... }: 12 + { 13 + ${host.class}.networking.hostName = host.name; 14 + } 15 + ) 16 + ]; 17 + 18 + expr = igloo.networking.hostName; 19 + expected = "igloo"; 20 + } 21 + ); 22 + 23 + test-homemanager-applies-to-all-users = denTest ( 24 + { 25 + den, 26 + tuxHm, 27 + pinguHm, 28 + ... 29 + }: 30 + { 31 + den.hosts.x86_64-linux.igloo.users = { 32 + tux = { }; 33 + pingu = { }; 34 + }; 35 + den.default.homeManager.home.stateVersion = "25.11"; 36 + den.default.homeManager.programs.fish.enable = true; 37 + 38 + expr = [ 39 + tuxHm.programs.fish.enable 40 + pinguHm.programs.fish.enable 41 + ]; 42 + expected = [ 43 + true 44 + true 45 + ]; 46 + } 47 + ); 48 + 49 + test-dynamic-class-in-user-host-context = denTest ( 50 + { den, igloo, ... }: 51 + { 52 + den.hosts.x86_64-linux.igloo.users.tux = { }; 53 + den.default.includes = [ 54 + ( 55 + { user, host, ... }: 56 + { 57 + ${host.class}.users.users.${user.userName}.description = "${user.userName} on ${host.name}"; 58 + } 59 + ) 60 + ]; 61 + 62 + expr = igloo.users.users.tux.description; 63 + expected = "tux on igloo"; 64 + } 65 + ); 66 + 67 + }; 68 + }
+77
templates/ci/modules/features/forward.nix
··· 1 + { denTest, ... }: 2 + { 3 + flake.tests.forward = { 4 + 5 + test-forward-custom-class-to-nixos = denTest ( 6 + { 7 + den, 8 + lib, 9 + igloo, 10 + ... 11 + }: 12 + let 13 + forwarded = 14 + { class, aspect-chain }: 15 + den._.forward { 16 + each = lib.singleton class; 17 + fromClass = _: "custom"; 18 + intoClass = _: "nixos"; 19 + intoPath = _: [ ]; 20 + fromAspect = _: lib.head aspect-chain; 21 + }; 22 + in 23 + { 24 + den.hosts.x86_64-linux.igloo.users.tux = { }; 25 + den.aspects.igloo = { 26 + includes = [ forwarded ]; 27 + custom.networking.hostName = "from-custom-class"; 28 + }; 29 + 30 + expr = igloo.networking.hostName; 31 + expected = "from-custom-class"; 32 + } 33 + ); 34 + 35 + test-forward-into-subpath = denTest ( 36 + { 37 + den, 38 + lib, 39 + igloo, 40 + ... 41 + }: 42 + let 43 + fwdModule = { 44 + options.items = lib.mkOption { type = lib.types.listOf lib.types.str; }; 45 + }; 46 + 47 + forwarded = 48 + { class, aspect-chain }: 49 + den._.forward { 50 + each = lib.singleton class; 51 + fromClass = _: "src"; 52 + intoClass = _: "nixos"; 53 + intoPath = _: [ "fwd-box" ]; 54 + fromAspect = _: lib.head aspect-chain; 55 + }; 56 + in 57 + { 58 + den.hosts.x86_64-linux.igloo.users.tux = { }; 59 + den.aspects.igloo = { 60 + includes = [ forwarded ]; 61 + nixos.imports = [ 62 + { options.fwd-box = lib.mkOption { type = lib.types.submoduleWith { modules = [ fwdModule ]; }; }; } 63 + ]; 64 + nixos.fwd-box.items = [ "from-nixos-owned" ]; 65 + src.items = [ "from-src-class" ]; 66 + }; 67 + 68 + expr = lib.sort (a: b: a < b) igloo.fwd-box.items; 69 + expected = [ 70 + "from-nixos-owned" 71 + "from-src-class" 72 + ]; 73 + } 74 + ); 75 + 76 + }; 77 + }
+46
templates/ci/modules/features/home-manager/home-managed-home.nix
··· 1 + { denTest, ... }: 2 + { 3 + 4 + flake.tests.home-manager-managed-home = { 5 + 6 + test-program-enabled = denTest ( 7 + { 8 + den, 9 + lib, 10 + config, 11 + tuxHm, 12 + ... 13 + }: 14 + { 15 + den.hosts.x86_64-linux.igloo.users.tux = { }; 16 + 17 + den.default.homeManager.home.stateVersion = "25.11"; 18 + den.aspects.tux.homeManager.programs.vim.enable = true; 19 + 20 + expr = tuxHm.programs.vim.enable; 21 + expected = true; 22 + } 23 + ); 24 + 25 + test-homedir-defined = denTest ( 26 + { 27 + den, 28 + lib, 29 + config, 30 + tuxHm, 31 + ... 32 + }: 33 + { 34 + den.hosts.x86_64-linux.igloo.users.tux = { }; 35 + 36 + den.default.homeManager.home.stateVersion = "25.11"; 37 + den.default.includes = [ den._.define-user ]; 38 + 39 + expr = tuxHm.home.homeDirectory; 40 + expected = "/home/tux"; 41 + } 42 + ); 43 + 44 + }; 45 + 46 + }
+39
templates/ci/modules/features/home-manager/use-global-pkgs.nix
··· 1 + { denTest, ... }: 2 + { 3 + flake.tests.home-manager-use-global-pkgs = { 4 + 5 + test-enabled = denTest ( 6 + { den, igloo, ... }: 7 + { 8 + den.hosts.x86_64-linux.igloo.users.tux = { }; 9 + 10 + # hm-host context is activated when host has HM support 11 + den.ctx.hm-host.nixos.home-manager.useGlobalPkgs = true; 12 + 13 + expr = igloo.home-manager.useGlobalPkgs; 14 + expected = true; 15 + } 16 + ); 17 + 18 + test-disabled = denTest ( 19 + { den, igloo, ... }: 20 + { 21 + den.hosts.x86_64-linux.igloo.users.tux = { }; 22 + expr = igloo.home-manager.useGlobalPkgs; 23 + expected = false; 24 + } 25 + ); 26 + 27 + test-not-activated-without-hm-users = denTest ( 28 + { den, config, ... }: 29 + { 30 + den.hosts.x86_64-linux.igloo = { }; 31 + den.ctx.hm-host.nixos.home-manager.useGlobalPkgs = true; 32 + 33 + expr = config.flake.nixosConfigurations.igloo.config ? home-manager; 34 + expected = false; 35 + } 36 + ); 37 + 38 + }; 39 + }
+57
templates/ci/modules/features/homes.nix
··· 1 + { denTest, ... }: 2 + { 3 + flake.tests.standalone-homes = { 4 + 5 + test-home-configuration-created = denTest ( 6 + { den, config, ... }: 7 + { 8 + den.homes.x86_64-linux.tux = { }; 9 + den.default.homeManager.home.stateVersion = "25.11"; 10 + 11 + expr = config.flake.homeConfigurations ? tux; 12 + expected = true; 13 + } 14 + ); 15 + 16 + test-home-aspect-config-applied = denTest ( 17 + { den, config, ... }: 18 + { 19 + den.homes.x86_64-linux.tux = { }; 20 + den.default.homeManager.home.stateVersion = "25.11"; 21 + den.default.includes = [ den._.define-user ]; 22 + den.aspects.tux.homeManager.programs.fish.enable = true; 23 + 24 + expr = config.flake.homeConfigurations.tux.config.programs.fish.enable; 25 + expected = true; 26 + } 27 + ); 28 + 29 + test-home-custom-username = denTest ( 30 + { den, config, ... }: 31 + { 32 + den.homes.x86_64-linux.cam = { 33 + userName = "cameron"; 34 + }; 35 + den.default.homeManager.home.stateVersion = "25.11"; 36 + den.default.includes = [ den._.define-user ]; 37 + 38 + expr = config.flake.homeConfigurations.cam.config.home.username; 39 + expected = "cameron"; 40 + } 41 + ); 42 + 43 + test-ctx-home-applies-aspect = denTest ( 44 + { den, config, ... }: 45 + { 46 + den.homes.x86_64-linux.tux = { }; 47 + den.default.homeManager.home.stateVersion = "25.11"; 48 + den.default.includes = [ den._.define-user ]; 49 + den.ctx.home.homeManager.programs.vim.enable = true; 50 + 51 + expr = config.flake.homeConfigurations.tux.config.programs.vim.enable; 52 + expected = true; 53 + } 54 + ); 55 + 56 + }; 57 + }
+77
templates/ci/modules/features/host-options.nix
··· 1 + { denTest, ... }: 2 + { 3 + flake.tests.host-options = { 4 + 5 + test-custom-hostname-attr = denTest ( 6 + { den, ... }: 7 + { 8 + den.hosts.x86_64-linux.igloo = { 9 + hostName = "polar-station"; 10 + users.tux = { }; 11 + }; 12 + 13 + expr = den.hosts.x86_64-linux.igloo.hostName; 14 + expected = "polar-station"; 15 + } 16 + ); 17 + 18 + test-hostname-used-in-networking = denTest ( 19 + { den, igloo, ... }: 20 + { 21 + den.hosts.x86_64-linux.igloo.users.tux = { }; 22 + den.default.homeManager.home.stateVersion = "25.11"; 23 + den.default.includes = [ 24 + ( 25 + { host, ... }: 26 + { 27 + ${host.class}.networking.hostName = host.hostName; 28 + } 29 + ) 30 + ]; 31 + 32 + expr = igloo.networking.hostName; 33 + expected = "igloo"; 34 + } 35 + ); 36 + 37 + test-custom-aspect-name = denTest ( 38 + { den, config, ... }: 39 + { 40 + den.hosts.x86_64-linux.igloo = { 41 + aspect = "my-custom-aspect"; 42 + users.tux = { }; 43 + }; 44 + den.default.homeManager.home.stateVersion = "25.11"; 45 + den.aspects.my-custom-aspect.nixos.networking.hostName = "from-custom"; 46 + 47 + expr = config.flake.nixosConfigurations.igloo.config.networking.hostName; 48 + expected = "from-custom"; 49 + } 50 + ); 51 + 52 + test-default-aspect-is-name = denTest ( 53 + { den, ... }: 54 + { 55 + den.hosts.x86_64-linux.igloo.users.tux = { }; 56 + 57 + expr = den.hosts.x86_64-linux.igloo.aspect; 58 + expected = "igloo"; 59 + } 60 + ); 61 + 62 + test-user-custom-username = denTest ( 63 + { den, igloo, ... }: 64 + { 65 + den.hosts.x86_64-linux.igloo.users.tux = { 66 + userName = "penguin"; 67 + }; 68 + den.default.homeManager.home.stateVersion = "25.11"; 69 + den.aspects.igloo.includes = [ den._.define-user ]; 70 + 71 + expr = igloo.users.users.penguin.isNormalUser; 72 + expected = true; 73 + } 74 + ); 75 + 76 + }; 77 + }
+95
templates/ci/modules/features/namespaces.nix
··· 1 + { denTest, inputs, ... }: 2 + { 3 + 4 + flake.tests.namespaces = { 5 + 6 + test-local-definition = denTest ( 7 + { den, ns, ... }: 8 + { 9 + imports = [ (inputs.den.namespace "ns" false) ]; 10 + ns.foo.nixos.truth = true; 11 + expr = ns.foo ? nixos; 12 + expected = true; 13 + } 14 + ); 15 + 16 + test-merge-definition = denTest ( 17 + { den, ns, ... }: 18 + { 19 + imports = 20 + let 21 + external.denful.ns.foo.nixos.name = [ "source" ]; 22 + in 23 + [ (inputs.den.namespace "ns" [ external ]) ]; 24 + expr = ns.foo ? nixos; 25 + expected = true; 26 + } 27 + ); 28 + 29 + test-multiple-sources-merged = denTest ( 30 + { 31 + den, 32 + lib, 33 + ns, 34 + igloo, 35 + ... 36 + }: 37 + let 38 + srcA.denful.ns.gear.nixos.data = [ "from-A" ]; 39 + srcB.denful.ns.gear.nixos.data = [ "from-B" ]; 40 + dataMod = { 41 + options.data = lib.mkOption { type = lib.types.listOf lib.types.str; }; 42 + }; 43 + in 44 + { 45 + imports = [ 46 + (inputs.den.namespace "ns" [ 47 + srcA 48 + srcB 49 + true 50 + ]) 51 + ]; 52 + den.hosts.x86_64-linux.igloo.users.tux = { }; 53 + ns.gear.nixos.data = [ "local" ]; 54 + ns.gear.nixos.imports = [ dataMod ]; 55 + den.aspects.igloo.includes = [ ns.gear ]; 56 + 57 + expr = lib.sort (a: b: a < b) igloo.data; 58 + expected = [ 59 + "from-A" 60 + "from-B" 61 + "local" 62 + ]; 63 + } 64 + ); 65 + 66 + test-provides-underscore-syntax = denTest ( 67 + { den, ns, ... }: 68 + { 69 + imports = [ (inputs.den.namespace "ns" true) ]; 70 + ns.root.provides.branch.provides.leaf.nixos.truth = true; 71 + 72 + expr = ns.root._.branch._.leaf ? nixos; 73 + expected = true; 74 + } 75 + ); 76 + 77 + test-namespace-as-flake-output = denTest ( 78 + { 79 + den, 80 + ns, 81 + config, 82 + ... 83 + }: 84 + { 85 + imports = [ (inputs.den.namespace "ns" true) ]; 86 + ns.foo.nixos.truth = true; 87 + 88 + expr = config.flake.denful ? ns; 89 + expected = true; 90 + } 91 + ); 92 + 93 + }; 94 + 95 + }
+122
templates/ci/modules/features/parametric.nix
··· 1 + { denTest, ... }: 2 + { 3 + flake.tests.parametric = { 4 + 5 + test-parametric-forwards-context = denTest ( 6 + { den, igloo, ... }: 7 + let 8 + foo = den.lib.parametric { 9 + includes = [ 10 + ( 11 + { host, ... }: 12 + { 13 + nixos.users.users.tux.description = host.name; 14 + } 15 + ) 16 + ]; 17 + }; 18 + in 19 + { 20 + den.hosts.x86_64-linux.igloo.users.tux = { }; 21 + den.aspects.igloo.includes = [ foo ]; 22 + 23 + expr = igloo.users.users.tux.description; 24 + expected = "igloo"; 25 + } 26 + ); 27 + 28 + test-parametric-owned-config = denTest ( 29 + { den, igloo, ... }: 30 + let 31 + foo = den.lib.parametric { 32 + nixos.networking.hostName = "from-parametric-owned"; 33 + includes = [ ]; 34 + }; 35 + in 36 + { 37 + den.hosts.x86_64-linux.igloo.users.tux = { }; 38 + den.aspects.igloo.includes = [ foo ]; 39 + 40 + expr = igloo.networking.hostName; 41 + expected = "from-parametric-owned"; 42 + } 43 + ); 44 + 45 + test-parametric-fixedTo = denTest ( 46 + { den, igloo, ... }: 47 + let 48 + foo = 49 + { host, ... }: 50 + den.lib.parametric.fixedTo { planet = "Earth"; } { 51 + includes = [ 52 + ( 53 + { planet, ... }: 54 + { 55 + nixos.users.users.tux.description = planet; 56 + } 57 + ) 58 + ]; 59 + }; 60 + in 61 + { 62 + den.hosts.x86_64-linux.igloo.users.tux = { }; 63 + den.aspects.igloo.includes = [ foo ]; 64 + 65 + expr = igloo.users.users.tux.description; 66 + expected = "Earth"; 67 + } 68 + ); 69 + 70 + test-parametric-expands = denTest ( 71 + { den, igloo, ... }: 72 + let 73 + foo = den.lib.parametric.expands { planet = "Earth"; } { 74 + includes = [ 75 + ( 76 + { host, planet, ... }: 77 + { 78 + nixos.users.users.tux.description = "${host.name}/${planet}"; 79 + } 80 + ) 81 + ]; 82 + }; 83 + in 84 + { 85 + den.hosts.x86_64-linux.igloo.users.tux = { }; 86 + den.aspects.igloo.includes = [ foo ]; 87 + 88 + expr = igloo.users.users.tux.description; 89 + expected = "igloo/Earth"; 90 + } 91 + ); 92 + 93 + test-never-matches-aspect-skipped = denTest ( 94 + { den, igloo, ... }: 95 + let 96 + never-matches = 97 + { never-exists, ... }: 98 + { 99 + nixos.networking.hostName = "NEVER"; 100 + }; 101 + sets-hostname = 102 + { host, ... }: 103 + { 104 + nixos.networking.hostName = host.name; 105 + }; 106 + in 107 + { 108 + den.hosts.x86_64-linux.igloo.users.tux = { }; 109 + den.aspects.igloo = den.lib.parametric { 110 + includes = [ 111 + sets-hostname 112 + never-matches 113 + ]; 114 + }; 115 + 116 + expr = igloo.networking.hostName; 117 + expected = "igloo"; 118 + } 119 + ); 120 + 121 + }; 122 + }
+80
templates/ci/modules/features/schema-base-modules.nix
··· 1 + # Copy this file to start new tests 2 + { denTest, ... }: 3 + { 4 + flake.tests.schema-base-modules = { 5 + 6 + test-host-base = denTest ( 7 + { den, lib, ... }: 8 + { 9 + den.base.host = 10 + { host, ... }: 11 + { 12 + options.vpn-alias = lib.mkOption { default = host.name; }; 13 + }; 14 + 15 + den.hosts.x86_64-linux.igloo.users.tux = { }; 16 + 17 + expr = den.hosts.x86_64-linux.igloo.vpn-alias; 18 + expected = "igloo"; 19 + } 20 + ); 21 + 22 + test-user-base = denTest ( 23 + { den, lib, ... }: 24 + { 25 + den.base.user = 26 + { user, ... }: 27 + { 28 + options.main-group = lib.mkOption { default = user.name; }; 29 + }; 30 + 31 + den.hosts.x86_64-linux.igloo.users.tux = { }; 32 + 33 + expr = den.hosts.x86_64-linux.igloo.users.tux.main-group; 34 + expected = "tux"; 35 + } 36 + ); 37 + 38 + test-home-base = denTest ( 39 + { den, lib, ... }: 40 + { 41 + den.base.home = 42 + { home, ... }: 43 + { 44 + options.main-group = lib.mkOption { default = home.name; }; 45 + }; 46 + 47 + den.homes.x86_64-linux.tux = { }; 48 + 49 + expr = den.homes.x86_64-linux.tux.main-group; 50 + expected = "tux"; 51 + } 52 + ); 53 + 54 + test-conf-base = denTest ( 55 + { den, lib, ... }: 56 + { 57 + den.base.conf = 58 + { ... }: 59 + { 60 + options.foo = lib.mkOption { default = "foo"; }; 61 + }; 62 + 63 + den.hosts.x86_64-linux.igloo.users.tux = { }; 64 + den.homes.x86_64-linux.tux = { }; 65 + 66 + expr = [ 67 + den.hosts.x86_64-linux.igloo.foo 68 + den.hosts.x86_64-linux.igloo.users.tux.foo 69 + den.homes.x86_64-linux.tux.foo 70 + ]; 71 + expected = [ 72 + "foo" 73 + "foo" 74 + "foo" 75 + ]; 76 + } 77 + ); 78 + 79 + }; 80 + }
+40
templates/ci/modules/features/special-args-custom-instantiate.nix
··· 1 + { denTest, inputs, ... }: 2 + { 3 + 4 + flake.tests.special-args-custom-instantiate = { 5 + 6 + test-standalone-hm-os-config = denTest ( 7 + { den, config, ... }: 8 + { 9 + 10 + den.hosts.x86_64-linux.igloo = { }; 11 + 12 + den.homes.x86_64-linux.pingu = { 13 + instantiate = 14 + { pkgs, modules }: 15 + inputs.home-manager.lib.homeManagerConfiguration { 16 + inherit pkgs modules; 17 + extraSpecialArgs.osConfig = config.flake.nixosConfigurations.igloo.config; 18 + }; 19 + }; 20 + 21 + den.default.homeManager.home.stateVersion = "25.11"; 22 + 23 + den.aspects.igloo.nixos.programs.vim.enable = true; 24 + den.aspects.pingu.homeManager = 25 + { osConfig, ... }: 26 + { 27 + programs.emacs.enable = osConfig.programs.vim.enable; 28 + }; 29 + 30 + den.aspects.pingu.includes = [ den._.define-user ]; 31 + 32 + expr = config.flake.homeConfigurations.pingu.config.programs.emacs.enable; 33 + expected = true; 34 + 35 + } 36 + ); 37 + 38 + }; 39 + 40 + }
+60
templates/ci/modules/features/top-level-parametric.nix
··· 1 + { denTest, ... }: 2 + { 3 + flake.tests.top-level-parametric = { 4 + 5 + test-user-aspect-with-context = denTest ( 6 + { den, igloo, ... }: 7 + let 8 + custom-user-config = 9 + { user, ... }: 10 + { 11 + nixos.users.users.tux.description = user.userName; 12 + }; 13 + in 14 + { 15 + den.hosts.x86_64-linux.igloo.users.tux = { }; 16 + den.aspects.tux.includes = [ custom-user-config ]; 17 + 18 + expr = igloo.users.users.tux.description; 19 + expected = "tux"; 20 + } 21 + ); 22 + 23 + test-host-aspect-with-context = denTest ( 24 + { den, igloo, ... }: 25 + let 26 + custom-host-config = 27 + { host, ... }: 28 + { 29 + nixos.networking.hostName = host.name; 30 + }; 31 + in 32 + { 33 + den.hosts.x86_64-linux.igloo.users.tux = { }; 34 + den.aspects.igloo.includes = [ custom-host-config ]; 35 + 36 + expr = igloo.networking.hostName; 37 + expected = "igloo"; 38 + } 39 + ); 40 + 41 + test-user-and-host-context = denTest ( 42 + { den, igloo, ... }: 43 + let 44 + from-both = 45 + { host, user, ... }: 46 + { 47 + nixos.users.users.tux.description = "${user.userName}@${host.name}"; 48 + }; 49 + in 50 + { 51 + den.hosts.x86_64-linux.igloo.users.tux = { }; 52 + den.aspects.tux.includes = [ from-both ]; 53 + 54 + expr = igloo.users.users.tux.description; 55 + expected = "tux@igloo"; 56 + } 57 + ); 58 + 59 + }; 60 + }
+190
templates/ci/modules/features/user-host-bidirectional-config.nix
··· 1 + { denTest, ... }: 2 + { 3 + flake.tests.user-host-bidirectional-config = { 4 + 5 + test-host-owned-configures-all-users = denTest ( 6 + { 7 + den, 8 + tuxHm, 9 + pinguHm, 10 + ... 11 + }: 12 + { 13 + den.default.homeManager.home.stateVersion = "25.11"; 14 + 15 + den.hosts.x86_64-linux.igloo.users = { 16 + tux = { }; 17 + pingu = { }; 18 + }; 19 + 20 + den.aspects.igloo.homeManager.programs.direnv.enable = true; 21 + 22 + expr = [ 23 + tuxHm.programs.direnv.enable 24 + pinguHm.programs.direnv.enable 25 + ]; 26 + expected = [ 27 + true 28 + true 29 + ]; 30 + } 31 + ); 32 + 33 + test-host-static-configures-all-users = denTest ( 34 + { 35 + den, 36 + tuxHm, 37 + pinguHm, 38 + ... 39 + }: 40 + { 41 + den.default.homeManager.home.stateVersion = "25.11"; 42 + 43 + den.hosts.x86_64-linux.igloo.users = { 44 + tux = { }; 45 + pingu = { }; 46 + }; 47 + 48 + den.aspects.igloo.includes = [ 49 + { 50 + homeManager.programs.direnv.enable = true; 51 + } 52 + ]; 53 + 54 + expr = [ 55 + tuxHm.programs.direnv.enable 56 + pinguHm.programs.direnv.enable 57 + ]; 58 + expected = [ 59 + true 60 + true 61 + ]; 62 + } 63 + ); 64 + 65 + test-host-parametric-configures-all-users = denTest ( 66 + { 67 + den, 68 + tuxHm, 69 + pinguHm, 70 + ... 71 + }: 72 + { 73 + den.default.homeManager.home.stateVersion = "25.11"; 74 + 75 + den.hosts.x86_64-linux.igloo.users = { 76 + tux = { }; 77 + pingu = { }; 78 + }; 79 + 80 + den.aspects.igloo.includes = [ 81 + ( 82 + { host, user }: 83 + { 84 + homeManager.programs.direnv.enable = true; 85 + } 86 + ) 87 + ]; 88 + 89 + expr = [ 90 + tuxHm.programs.direnv.enable 91 + pinguHm.programs.direnv.enable 92 + ]; 93 + expected = [ 94 + true 95 + true 96 + ]; 97 + } 98 + ); 99 + 100 + test-user-owned-configures-all-hosts = denTest ( 101 + { 102 + den, 103 + igloo, 104 + iceberg, 105 + ... 106 + }: 107 + { 108 + den.default.homeManager.home.stateVersion = "25.11"; 109 + 110 + den.hosts.x86_64-linux.igloo.users.tux = { }; 111 + den.hosts.x86_64-linux.iceberg.users.tux = { }; 112 + 113 + den.aspects.tux.nixos.programs.fish.enable = true; 114 + 115 + expr = [ 116 + igloo.programs.fish.enable 117 + iceberg.programs.fish.enable 118 + ]; 119 + expected = [ 120 + true 121 + true 122 + ]; 123 + } 124 + ); 125 + 126 + test-user-static-configures-all-hosts = denTest ( 127 + { 128 + den, 129 + igloo, 130 + iceberg, 131 + ... 132 + }: 133 + { 134 + den.default.homeManager.home.stateVersion = "25.11"; 135 + 136 + den.hosts.x86_64-linux.igloo.users.tux = { }; 137 + den.hosts.x86_64-linux.iceberg.users.tux = { }; 138 + 139 + den.aspects.tux.includes = [ 140 + { 141 + nixos.programs.fish.enable = true; 142 + } 143 + ]; 144 + 145 + expr = [ 146 + igloo.programs.fish.enable 147 + iceberg.programs.fish.enable 148 + ]; 149 + expected = [ 150 + true 151 + true 152 + ]; 153 + } 154 + ); 155 + 156 + test-user-function-configures-all-hosts = denTest ( 157 + { 158 + den, 159 + igloo, 160 + iceberg, 161 + ... 162 + }: 163 + { 164 + den.default.homeManager.home.stateVersion = "25.11"; 165 + 166 + den.hosts.x86_64-linux.igloo.users.tux = { }; 167 + den.hosts.x86_64-linux.iceberg.users.tux = { }; 168 + 169 + den.aspects.tux.includes = [ 170 + ( 171 + { host, user }: 172 + { 173 + nixos.programs.fish.enable = true; 174 + } 175 + ) 176 + ]; 177 + 178 + expr = [ 179 + igloo.programs.fish.enable 180 + iceberg.programs.fish.enable 181 + ]; 182 + expected = [ 183 + true 184 + true 185 + ]; 186 + } 187 + ); 188 + 189 + }; 190 + }
-55
templates/ci/modules/forward.nix
··· 1 - { lib, den, ... }: 2 - let 3 - 4 - oneModule.foo = [ "one" ]; 5 - 6 - targetSubmodule = lib.mkOption { 7 - type = lib.types.submoduleWith { 8 - modules = [ 9 - { 10 - options.foo = lib.mkOption { 11 - type = lib.types.listOf lib.types.str; 12 - }; 13 - } 14 - ]; 15 - }; 16 - }; 17 - 18 - forwarded = 19 - { class, aspect-chain }: 20 - den._.forward { 21 - each = lib.singleton class; # item ignored 22 - fromClass = _item: "fwd-origin"; 23 - intoClass = _item: "nixos"; 24 - intoPath = _item: [ "fwd-target" ]; 25 - fromAspect = _item: lib.head aspect-chain; 26 - }; 27 - 28 - in 29 - { 30 - 31 - den.aspects.rockhopper = { 32 - includes = [ forwarded ]; 33 - nixos = { 34 - imports = [ { options.fwd-target = targetSubmodule; } ]; 35 - fwd-target = { 36 - foo = [ "zero" ]; 37 - imports = [ oneModule ]; 38 - }; 39 - }; 40 - fwd-origin.foo = [ "two" ]; 41 - }; 42 - 43 - perSystem = 44 - { rockhopper, checkCond, ... }: 45 - { 46 - checks.forward = checkCond "foo value was forwarded to os-level" ( 47 - rockhopper.config.fwd-target.foo == [ 48 - "two" 49 - "one" 50 - "zero" 51 - ] 52 - ); 53 - }; 54 - 55 - }
-37
templates/ci/modules/helpers.nix
··· 1 - { self, ... }: 2 - { 3 - perSystem = 4 - { pkgs, ... }: 5 - let 6 - checkFile = 7 - name: file: 8 - pkgs.runCommandLocal name { } '' 9 - ls -la ${file} | tee $out 10 - ''; 11 - 12 - checkCond = 13 - name: cond: 14 - let 15 - code = if cond then "touch $out" else ''echo "Cond-Failed: ${name}"''; 16 - in 17 - pkgs.runCommandLocal name { } code; 18 - 19 - rockhopper = self.nixosConfigurations.rockhopper; 20 - honeycrisp = self.darwinConfigurations.honeycrisp; 21 - adelie = self.wslConfigurations.adelie; 22 - cam = self.homeConfigurations.cam; 23 - bob = self.homeConfigurations.bob; 24 - luke = self.homeConfigurations.luke; 25 - 26 - alice-at-rockhopper = rockhopper.config.home-manager.users.alice; 27 - alice-at-honeycrisp = honeycrisp.config.home-manager.users.alice; 28 - in 29 - { 30 - _module.args = { 31 - inherit checkCond checkFile; 32 - inherit rockhopper honeycrisp adelie; 33 - inherit cam bob luke; 34 - inherit alice-at-rockhopper alice-at-honeycrisp; 35 - }; 36 - }; 37 - }
-28
templates/ci/modules/hm-enabled-host.nix
··· 1 - { den, inputs, ... }: 2 - { 3 - # The `{ HM-OS-HOST }` context is activated ONLY for hosts that have 4 - # a HM supported OS and at least one user with homeManager class. 5 - den.aspects.hm-global-pkgs = 6 - { HM-OS-HOST }: 7 - { 8 - nixos.home-manager.useGlobalPkgs = HM-OS-HOST.host.hostName == "rockhopper"; 9 - }; 10 - 11 - den.aspects.rockhopper.includes = [ den.aspects.hm-global-pkgs ]; 12 - 13 - den.hosts.x86_64-linux.no-homes = { }; 14 - 15 - perSystem = 16 - { checkCond, rockhopper, ... }: 17 - { 18 - checks.rockhopper-hm-global-pkgs = checkCond "rockhopper-hm-global-pkgs" ( 19 - rockhopper.config.home-manager.useGlobalPkgs 20 - ); 21 - 22 - checks.no-homes-hm-global-pkgs = checkCond "no-homes-hm-global-pkgs" ( 23 - # no home-manager enabled nor useGlobalPkgs 24 - !inputs.self.nixosConfigurations.no-homes.config ? home-manager.useGlobalPkgs 25 - ); 26 - }; 27 - 28 - }
-12
templates/ci/modules/home-managed.nix
··· 1 - { den, ... }: 2 - { 3 - # see batteries/home-manager.nix 4 - den.default.includes = [ den._.home-manager ]; 5 - 6 - # enable home-manager dependency. 7 - flake-file.inputs.home-manager = { 8 - url = "github:nix-community/home-manager"; 9 - inputs.nixpkgs.follows = "nixpkgs"; 10 - }; 11 - 12 - }
-31
templates/ci/modules/homes.nix
··· 1 - # Example standalone home-manager configurations. 2 - # These are independent of any host configuration. 3 - # See documentation at <den>/nix/types.nix 4 - { inputs, ... }: 5 - { 6 - den.homes.x86_64-linux.cam = { }; 7 - 8 - den.homes.aarch64-darwin.bob = { 9 - userName = "robert"; 10 - aspect = "developer"; 11 - }; 12 - 13 - # Example: custom home-manager instantiate for passing extraSpecialArgs. 14 - den.homes.x86_64-linux.luke = 15 - let 16 - osConfig = inputs.self.nixosConfigurations.rockhopper.config; 17 - in 18 - { 19 - # Example: luke standalone-homemanager needs access to rockhopper osConfig. 20 - instantiate = 21 - { pkgs, modules }: 22 - inputs.home-manager.lib.homeManagerConfiguration { 23 - inherit pkgs modules; 24 - extraSpecialArgs.osConfig = osConfig; 25 - }; 26 - 27 - # Example: custom attribute instead of specialArgs 28 - programToDependOn = "vim"; 29 - }; 30 - 31 - }
-13
templates/ci/modules/host-configures-users.nix
··· 1 - { 2 - 3 - # Example: host provides static config to all its users hm. 4 - den.aspects.rockhopper.homeManager.programs.direnv.enable = true; 5 - 6 - perSystem = 7 - { checkCond, alice-at-rockhopper, ... }: 8 - { 9 - checks.host-contributes-to-user = checkCond "rockhopper contributes to all its users" ( 10 - alice-at-rockhopper.programs.direnv.enable 11 - ); 12 - }; 13 - }
-48
templates/ci/modules/host-user-conditional-hm.nix
··· 1 - { lib, ... }: 2 - let 3 - # Example: configuration that depends on both host and user. provides only to HM. 4 - program-conditional = 5 - program: 6 - { 7 - user, 8 - host, 9 - ... 10 - }: 11 - if user.userName == "alice" && !lib.hasSuffix "darwin" host.system then 12 - { 13 - homeManager.programs.${program}.enable = true; 14 - } 15 - else 16 - { }; 17 - in 18 - { 19 - 20 - # Example: host parametric includes. conditional user configuration. 21 - den.aspects.rockhopper.includes = [ (program-conditional "git") ]; 22 - 23 - # Example: user parametric includes 24 - den.aspects.alice.includes = [ (program-conditional "mpv") ]; 25 - 26 - perSystem = 27 - { 28 - checkCond, 29 - alice-at-rockhopper, 30 - alice-at-honeycrisp, 31 - ... 32 - }: 33 - { 34 - 35 - checks.alice-hm-git-enabled-on = checkCond "home-managed git for alice at rockhopper" ( 36 - alice-at-rockhopper.programs.git.enable 37 - ); 38 - checks.alice-hm-git-enabled-off = checkCond "home-managed git for alice at honeycrisp" ( 39 - !alice-at-honeycrisp.programs.git.enable 40 - ); 41 - 42 - checks.alice-hm-mpv-enabled-rockhopper = checkCond "home-managed mpv for alice at rockhopper" ( 43 - alice-at-rockhopper.programs.mpv.enable 44 - ); 45 - 46 - }; 47 - 48 - }
-50
templates/ci/modules/hosts.nix
··· 1 - # This is a fully working example configuration. 2 - # Feel free to remove it, adapt or split into several modules. 3 - # See documentation at <den>/nix/types.nix 4 - { inputs, ... }: 5 - { 6 - den.hosts.aarch64-darwin.honeycrisp.users.alice = { }; 7 - 8 - den.hosts.aarch64-linux.emperor.users.alice = { }; 9 - 10 - den.hosts.x86_64-linux = { 11 - rockhopper = { 12 - description = "rockhopper is a kind of penguin"; 13 - users.alice = { }; 14 - }; 15 - 16 - adelie = { 17 - description = "wsl on windows"; 18 - users.will = { }; 19 - intoAttr = "wslConfigurations"; 20 - # custom nixpkgs channel. 21 - instantiate = inputs.nixpkgs-stable.lib.nixosSystem; 22 - # custom attribute (see home-manager.nix) 23 - hm-module = inputs.home-manager-stable.nixosModules.home-manager; 24 - # custom attribute (see primary-user.nix) 25 - wsl = { }; 26 - }; 27 - }; 28 - 29 - # move these inputs to any module you want. 30 - # they are here for all our examples to work on CI. 31 - flake-file.inputs = { 32 - 33 - # these stable inputs are for wsl 34 - nixpkgs-stable.url = "github:nixos/nixpkgs/release-25.05"; 35 - home-manager-stable.url = "github:nix-community/home-manager/release-25.05"; 36 - home-manager-stable.inputs.nixpkgs.follows = "nixpkgs-stable"; 37 - 38 - nixos-wsl = { 39 - url = "github:nix-community/nixos-wsl"; 40 - inputs.nixpkgs.follows = "nixpkgs-stable"; 41 - inputs.flake-compat.follows = ""; 42 - }; 43 - 44 - darwin = { 45 - url = "github:nix-darwin/nix-darwin"; 46 - inputs.nixpkgs.follows = "nixpkgs"; 47 - }; 48 - }; 49 - 50 - }
-81
templates/ci/modules/namespace.nix
··· 1 - { 2 - inputs, 3 - den, 4 - lib, 5 - eg, 6 - # deadnix: skip 7 - __findFile ? __findFile, 8 - ... 9 - }: 10 - let 11 - # module for testing inclusion of namespaces 12 - simsModule.nixos.options.sims = lib.mkOption { 13 - type = lib.types.listOf lib.types.str; 14 - }; 15 - in 16 - { 17 - # enable <angle/bracket> syntax for finding aspects. 18 - _module.args.__findFile = den.lib.__findFile; 19 - 20 - imports = [ 21 - # create a local namespace and output at flake.denful.eg 22 - (inputs.den.namespace "eg" true) 23 - 24 - # you can also mount a namespace from many input sources. 25 - # the second argument becomes an array of inputs. 26 - ( 27 - let 28 - # NOTE: here we simulate inputA and inputB are flakes. 29 - inputA.denful.sim.ul._.a._.tion.nixos.sims = [ "inputA simulation" ]; 30 - inputB.denful.sim.ul._.a._.tion.nixos.sims = [ "inputB simulation" ]; 31 - exposeToFlake = true; 32 - in 33 - inputs.den.namespace "sim" [ 34 - inputA 35 - inputB 36 - exposeToFlake 37 - ] 38 - ) 39 - ]; 40 - 41 - # define nested aspects in local namespace 42 - eg.foo.provides.bar.provides.baz = { 43 - nixos.sims = [ "local namespace" ]; 44 - }; 45 - 46 - # augment aspects on a mounted namespace 47 - sim.ul._.a._.tion.nixos.sims = [ "local simulation" ]; 48 - 49 - den.aspects.rockhopper.includes = [ 50 - simsModule 51 - <eg/foo/bar/baz> 52 - <sim/ul/a/tion> 53 - ]; 54 - 55 - perSystem = 56 - { checkCond, rockhopper, ... }: 57 - { 58 - checks.namespace-eg-flake-output = checkCond "namespace enabled as flake output" ( 59 - eg == den.ful.eg && eg == <eg> && eg == inputs.self.denful.eg 60 - ); 61 - 62 - checks.namespace-eg-provides-accessible = checkCond "exact same value" ( 63 - eg.foo._.bar._.baz == <eg/foo/bar/baz> 64 - && eg.foo._.bar._.baz == inputs.self.denful.eg.foo._.bar._.baz 65 - ); 66 - 67 - checks.namespace-sim-merged = checkCond "merges from all sources" ( 68 - let 69 - expected = [ 70 - "inputA simulation" 71 - "inputB simulation" 72 - "local namespace" 73 - "local simulation" 74 - ]; 75 - actual = lib.sort (a: b: a < b) rockhopper.config.sims; 76 - in 77 - expected == actual 78 - ); 79 - 80 - }; 81 - }
-41
templates/ci/modules/one-os-package-per-user.nix
··· 1 - let 2 - 3 - # Example: adds hello into each user. provides only to OS. 4 - hello-package-for-user = 5 - { 6 - user, 7 - host, 8 - ... 9 - }: 10 - { 11 - ${host.class} = 12 - { pkgs, ... }: 13 - { 14 - users.users.${user.userName}.packages = [ pkgs.hello ]; 15 - }; 16 - }; 17 - 18 - in 19 - { 20 - 21 - den.default.includes = [ hello-package-for-user ]; 22 - 23 - perSystem = 24 - { 25 - checkCond, 26 - rockhopper, 27 - lib, 28 - ... 29 - }: 30 - { 31 - checks.alice-hello-enabled-by-default = checkCond "added hello at user packages" ( 32 - let 33 - progs = rockhopper.config.users.users.alice.packages; 34 - expr = map lib.getName progs; 35 - expected = [ "hello" ]; 36 - in 37 - expr == expected 38 - ); 39 - }; 40 - 41 - }
-145
templates/ci/modules/parametric-with-owned.nix
··· 1 - { 2 - den, 3 - lib, 4 - ... 5 - }: 6 - let 7 - # a test module to check context was forwarded 8 - fwdModule.options.fwd = { 9 - a = strOpt; 10 - b = strOpt; 11 - c = strOpt; 12 - d = strOpt; 13 - e = strOpt; 14 - f = strOpt; 15 - # unlike strings, pkgs cannot be duplicated/merged, we use this to 16 - # ensure no-dups are created from parametric owned modules. 17 - pkg = pkgOpt; 18 - pkg2 = pkgOpt; 19 - pkg3 = pkgOpt; 20 - }; 21 - strOpt = lib.mkOption { type = lib.types.str; }; 22 - pkgOpt = lib.mkOption { type = lib.types.package; }; 23 - 24 - inherit (den.lib) parametric; 25 - in 26 - { 27 - den.aspects.rockhopper.includes = [ 28 - { nixos.imports = [ fwdModule ]; } 29 - { homeManager.imports = [ fwdModule ]; } 30 - den.aspects.fwd._.first 31 - ]; 32 - den.aspects.rockhopper.nixos.fwd.c = "host owned C"; 33 - den.aspects.rockhopper.homeManager.fwd.a = "host home-managed A"; 34 - 35 - # this aspect will take any context and also forward it 36 - # into any includes function that can take same context. 37 - den.aspects.fwd._.first = parametric { 38 - nixos = 39 - { pkgs, ... }: 40 - { 41 - fwd.a = "First owned A"; 42 - fwd.pkg = pkgs.hello; 43 - }; 44 - homeManager = 45 - { pkgs, ... }: 46 - { 47 - fwd.pkg = pkgs.vim; 48 - }; 49 - includes = [ 50 - den.aspects.fwd._.second 51 - { nixos.fwd.d = "First static includes D"; } 52 - den.aspects.fwd._.never 53 - den.aspects.fwd._.fourth 54 - ]; 55 - }; 56 - 57 - # Note that second has named arguments, while first does not. 58 - # the first aspect forwards whatever context it receives. 59 - den.aspects.fwd._.second = 60 - { host, ... }: 61 - parametric.fixedTo { third = "Impact"; } { 62 - includes = [ den.aspects.fwd._.third ]; 63 - nixos = 64 - { pkgs, ... }: 65 - { 66 - fwd.b = "Second owned B for ${host.name}"; 67 - fwd.pkg2 = pkgs.bat; 68 - }; 69 - homeManager = 70 - { pkgs, ... }: 71 - { 72 - fwd.pkg2 = pkgs.helix; 73 - }; 74 - }; 75 - 76 - den.aspects.fwd._.third = 77 - { third, ... }: 78 - { 79 - nixos.fwd.e = "Third ${third}"; 80 - }; 81 - 82 - den.aspects.fwd._.fourth = parametric.expands { planet = "Earth"; } { 83 - includes = [ den.aspects.fwd._.fifth ]; 84 - nixos = 85 - { pkgs, ... }: 86 - { 87 - fwd.pkg3 = pkgs.emacs-nox; 88 - }; 89 - homeManager = 90 - { pkgs, ... }: 91 - { 92 - fwd.pkg3 = pkgs.emacs-nox; 93 - }; 94 - }; 95 - 96 - den.aspects.fwd._.fifth = 97 - { host, planet, ... }: 98 - { 99 - nixos.fwd.f = "Fifth ${planet} ${host.name}"; 100 - }; 101 - 102 - den.aspects.fwd._.never = 103 - { never-matches }: 104 - { 105 - nixos.fwd.a = "Imposibru! should never be included ${never-matches}"; 106 - }; 107 - 108 - perSystem = 109 - { 110 - checkCond, 111 - rockhopper, 112 - alice-at-rockhopper, 113 - ... 114 - }: 115 - { 116 - checks.parametric-fwd-a = checkCond "fwd-a" (rockhopper.config.fwd.a == "First owned A"); 117 - checks.parametric-fwd-b = checkCond "fwd-b" ( 118 - rockhopper.config.fwd.b == "Second owned B for rockhopper" 119 - ); 120 - checks.parametric-fwd-c = checkCond "fwd-c" (rockhopper.config.fwd.c == "host owned C"); 121 - checks.parametric-fwd-d = checkCond "fwd-d" (rockhopper.config.fwd.d == "First static includes D"); 122 - checks.parametric-fwd-e = checkCond "fwd-e" (rockhopper.config.fwd.e == "Third Impact"); 123 - checks.parametric-fwd-f = checkCond "fwd-f" (rockhopper.config.fwd.f == "Fifth Earth rockhopper"); 124 - 125 - checks.parametric-fwd-pkg = checkCond "fwd-pkg" (lib.getName rockhopper.config.fwd.pkg == "hello"); 126 - checks.parametric-fwd-pkg2 = checkCond "fwd-pkg2" (lib.getName rockhopper.config.fwd.pkg2 == "bat"); 127 - checks.parametric-fwd-pkg3 = checkCond "fwd-pkg3" ( 128 - lib.getName rockhopper.config.fwd.pkg3 == "emacs-nox" 129 - ); 130 - 131 - checks.parametric-fwd-hm-a = checkCond "fwd-hm-a" ( 132 - alice-at-rockhopper.fwd.a == "host home-managed A" 133 - ); 134 - checks.parametric-fwd-hm-pkg = checkCond "fwd-hm-pkg" ( 135 - lib.getName alice-at-rockhopper.fwd.pkg == "vim" 136 - ); 137 - checks.parametric-fwd-hm-pkg2 = checkCond "fwd-hm-pkg2" ( 138 - lib.getName alice-at-rockhopper.fwd.pkg2 == "helix" 139 - ); 140 - checks.parametric-fwd-hm-pkg3 = checkCond "fwd-hm-pkg3" ( 141 - lib.getName alice-at-rockhopper.fwd.pkg3 == "emacs-nox" 142 - ); 143 - }; 144 - 145 - }
-29
templates/ci/modules/primary-user.nix
··· 1 - { den, ... }: 2 - { 3 - den.aspects.alice.includes = [ 4 - # alice is always admin in all its hosts 5 - den._.primary-user 6 - ]; 7 - 8 - den.aspects.will.includes = [ 9 - # will is primary user in WSL NixOS. 10 - den._.primary-user 11 - ]; 12 - 13 - perSystem = 14 - { 15 - checkCond, 16 - honeycrisp, 17 - adelie, 18 - ... 19 - }: 20 - { 21 - checks.alice-primary-on-macos = checkCond "den._.primary-user sets macos primary" ( 22 - honeycrisp.config.system.primaryUser == "alice" 23 - ); 24 - 25 - checks.will-is-wsl-default = checkCond "wsl.defaultUser defined" ( 26 - adelie.config.wsl.defaultUser == "will" 27 - ); 28 - }; 29 - }
-29
templates/ci/modules/set-hostname.nix
··· 1 - { 2 - den.default.includes = 3 - let 4 - # Example: parametric host aspect to automatically set hostName on any host. 5 - set-host-name = 6 - { host, ... }: 7 - { 8 - ${host.class}.networking.hostName = host.name; 9 - }; 10 - in 11 - [ set-host-name ]; 12 - 13 - perSystem = 14 - { 15 - checkCond, 16 - rockhopper, 17 - honeycrisp, 18 - ... 19 - }: 20 - { 21 - checks.rockhopper-hostname = checkCond "den.default.host.includes sets hostName" ( 22 - rockhopper.config.networking.hostName == "rockhopper" 23 - ); 24 - 25 - checks.honeycrisp-hostname = checkCond "den.default.host.includes sets hostName" ( 26 - honeycrisp.config.networking.hostName == "honeycrisp" 27 - ); 28 - }; 29 - }
-53
templates/ci/modules/shared-parametric-aspects.nix
··· 1 - { 2 - inputs, 3 - lib, 4 - shared, 5 - ... 6 - }: 7 - let 8 - dataModule.nixos.options.data = lib.mkOption { 9 - type = lib.types.listOf lib.types.str; 10 - }; 11 - mkInputFlake = name: { 12 - denful.shared.gaming._.retro._.sega = { 13 - nixos.data = [ "${name}-sega-static" ]; 14 - }; 15 - }; 16 - inputFoo = mkInputFlake "foo"; 17 - inputBar = mkInputFlake "bar"; 18 - in 19 - { 20 - imports = [ 21 - (inputs.den.namespace "shared" [ 22 - true 23 - inputFoo 24 - inputBar 25 - ]) 26 - ]; 27 - 28 - shared.gaming._.retro._.sega.nixos.data = [ "local-sega-static" ]; 29 - 30 - den.aspects.rockhopper.includes = [ 31 - dataModule 32 - shared.gaming._.retro._.sega 33 - ]; 34 - 35 - perSystem = 36 - { checkCond, rockhopper, ... }: 37 - let 38 - vals = lib.sort (a: b: a < b) rockhopper.config.data; 39 - in 40 - { 41 - checks.shared-parametric-all-merged = checkCond "all parametric merged" ( 42 - vals == [ 43 - "bar-sega-static" 44 - "foo-sega-static" 45 - "local-sega-static" 46 - ] 47 - ); 48 - 49 - checks.shared-flake-output-matches = checkCond "flake output matches" ( 50 - shared.gaming._.retro._.sega == inputs.self.denful.shared.gaming._.retro._.sega 51 - ); 52 - }; 53 - }
-70
templates/ci/modules/special-args.nix
··· 1 - { den, withSystem, ... }: 2 - let 3 - testModule = 4 - { 5 - inputs', 6 - lib, 7 - self', 8 - ... 9 - }: 10 - { 11 - options.specialArgsTest = { 12 - test-package = lib.mkOption { type = lib.types.package; }; 13 - neovim-package = lib.mkOption { type = lib.types.package; }; 14 - }; 15 - 16 - config.specialArgsTest = { 17 - test-package = self'.packages.hello; 18 - neovim-package = inputs'.neovim-nightly-overlay.packages.neovim; 19 - }; 20 - }; 21 - in 22 - { 23 - flake-file.inputs.neovim-nightly-overlay = { 24 - url = "github:nix-community/neovim-nightly-overlay"; 25 - inputs.nixpkgs.follows = "nixpkgs"; 26 - inputs.flake-parts.follows = "flake-parts"; 27 - }; 28 - 29 - den.default.includes = [ 30 - den._.self' 31 - den._.inputs' 32 - ]; 33 - 34 - den.aspects.rockhopper.nixos.imports = [ testModule ]; 35 - den.aspects.cam.homeManager.imports = [ testModule ]; 36 - 37 - flake.checks.x86_64-linux = withSystem "x86_64-linux" ( 38 - { 39 - checkCond, 40 - rockhopper, 41 - cam, 42 - self', 43 - inputs', 44 - ... 45 - }: 46 - { 47 - special-args-self-nixos = checkCond "self' provides same package to nixos" ( 48 - rockhopper.config.specialArgsTest.test-package == self'.packages.hello 49 - ); 50 - 51 - special-args-inputs-nixos = checkCond "inputs' provides same package to nixos" ( 52 - rockhopper.config.specialArgsTest.neovim-package == inputs'.neovim-nightly-overlay.packages.neovim 53 - ); 54 - 55 - special-args-self-hm = checkCond "self' provides same package to home-manager" ( 56 - cam.config.specialArgsTest.test-package == self'.packages.hello 57 - ); 58 - 59 - special-args-inputs-hm = checkCond "inputs' provides same package to home-manager" ( 60 - cam.config.specialArgsTest.neovim-package == inputs'.neovim-nightly-overlay.packages.neovim 61 - ); 62 - } 63 - ); 64 - 65 - perSystem = 66 - { pkgs, ... }: 67 - { 68 - packages.hello = pkgs.hello; 69 - }; 70 - }
-31
templates/ci/modules/standalone-hm-special-args-osconfig.nix
··· 1 - let 2 - 3 - # Example: luke standalone home-manager has access to rockhopper osConfig specialArg. 4 - os-conditional-hm = 5 - { home, ... }: 6 - { 7 - # access osConfig, wired via extraSpecialArgs in homes.nix. 8 - homeManager = 9 - { osConfig, ... }: 10 - { 11 - programs.bat.enable = osConfig.programs.${home.programToDependOn}.enable; 12 - }; 13 - }; 14 - in 15 - { 16 - 17 - # Example: standalone-hm config depends on osConfig (non-recursive) 18 - # NOTE: this will only work for standalone hm, and not for hosted hm 19 - # since a hosted hm configuration cannot depend on the os configuration. 20 - den.aspects.luke.includes = [ 21 - os-conditional-hm 22 - ]; 23 - 24 - perSystem = 25 - { checkCond, luke, ... }: 26 - { 27 - checks.luke-hm-depends-on-osConfig = checkCond "standalone hm can depend on osConfig" ( 28 - luke.config.programs.bat.enable 29 - ); 30 - }; 31 - }
+86
templates/ci/modules/test-support/eval-den.nix
··· 1 + { 2 + inputs, 3 + lib, 4 + withSystem, 5 + ... 6 + }: 7 + let 8 + # isolated test, prevent polution between tests. 9 + denTest = module: { 10 + inherit ((evalDen module).config) expr expected; 11 + }; 12 + 13 + evalDen = 14 + module: 15 + lib.evalModules { 16 + specialArgs = { 17 + inherit inputs; 18 + inherit withSystem; 19 + }; 20 + modules = [ 21 + module 22 + testModule 23 + helpersModule 24 + ]; 25 + }; 26 + 27 + testModule = { 28 + imports = [ inputs.den.flakeModule ]; 29 + options.flake.nixosConfigurations = lib.mkOption { }; 30 + options.flake.homeConfigurations = lib.mkOption { }; 31 + options.flake.packages = lib.mkOption { }; 32 + options.expr = lib.mkOption { }; 33 + options.expected = lib.mkOption { }; 34 + }; 35 + 36 + helpersModule = 37 + { config, ... }: 38 + let 39 + 40 + iceberg = config.flake.nixosConfigurations.iceberg.config; 41 + igloo = config.flake.nixosConfigurations.igloo.config; 42 + tuxHm = igloo.home-manager.users.tux; 43 + pinguHm = igloo.home-manager.users.pingu; 44 + 45 + sort = lib.sort (a: b: a < b); 46 + show = items: builtins.trace (lib.concatStringsSep " / " (lib.flatten [ items ])); 47 + 48 + funnyNames = 49 + aspect: 50 + let 51 + mod = aspect.resolve { class = "funny"; }; 52 + namesMod = { 53 + options.names = lib.mkOption { 54 + type = lib.types.listOf lib.types.str; 55 + default = [ ]; 56 + }; 57 + }; 58 + res = lib.evalModules { 59 + modules = [ 60 + mod 61 + namesMod 62 + ]; 63 + }; 64 + in 65 + sort res.config.names; 66 + 67 + in 68 + { 69 + _module.args = { 70 + inherit 71 + show 72 + funnyNames 73 + igloo 74 + iceberg 75 + tuxHm 76 + pinguHm 77 + ; 78 + }; 79 + }; 80 + 81 + in 82 + { 83 + _module.args = { inherit denTest evalDen; }; 84 + 85 + flake.packages.x86_64-linux.hello = inputs.nixpkgs.legacyPackages.x86_64-linux.hello; 86 + }
+9
templates/ci/modules/test-support/nix-unit.nix
··· 1 + { inputs, ... }: 2 + { 3 + systems = [ "x86_64-linux" ]; 4 + 5 + imports = [ inputs.nix-unit.modules.flake.default ]; 6 + 7 + perSystem.nix-unit.allowNetwork = true; 8 + perSystem.nix-unit.inputs = inputs; 9 + }
-50
templates/ci/modules/top-level-parametric.nix
··· 1 - # it is possible for top-level aspects directly under 2 - # den.aspects to take a context argument. 3 - { den, lib, ... }: 4 - let 5 - # A module to test that toplevel had context. 6 - topLevel = name: { 7 - config.tops = name; 8 - options.tops = lib.mkOption { type = lib.types.str; }; 9 - }; 10 - in 11 - { 12 - 13 - den.aspects.toplevel-user = 14 - { user, ... }: 15 - { 16 - nixos.imports = [ (topLevel user.name) ]; 17 - }; 18 - 19 - den.aspects.toplevel-host = 20 - { host, ... }: 21 - { 22 - homeManager.imports = [ (topLevel host.name) ]; 23 - }; 24 - 25 - den.aspects.rockhopper.includes = [ 26 - den.aspects.toplevel-host 27 - ]; 28 - 29 - den.aspects.alice.includes = [ 30 - den.aspects.toplevel-user 31 - ]; 32 - 33 - perSystem = 34 - { 35 - checkCond, 36 - alice-at-rockhopper, 37 - rockhopper, 38 - ... 39 - }: 40 - { 41 - checks.alice-toplevel-user = checkCond "alice toplevel param aspect" ( 42 - rockhopper.config.tops == "alice" 43 - ); 44 - 45 - checks.alice-toplevel-host = checkCond "alice toplevel param aspect" ( 46 - alice-at-rockhopper.tops == "rockhopper" 47 - ); 48 - }; 49 - 50 - }
-74
templates/ci/modules/unfree-and-inputs-nodups.nix
··· 1 - { 2 - den, 3 - lib, 4 - withSystem, 5 - inputs, 6 - ... 7 - }: 8 - { 9 - # we use another unfree-host and unfree-user because 10 - # unlike rockhopper, we need useGlobalPkgs=false for hm test. 11 - den.hosts.x86_64-linux.unfree-host.users.unfree-user = { }; 12 - # for testing home-manager nixpkgs.config: 13 - den.aspects.unfree-host.nixos.home-manager.useGlobalPkgs = false; 14 - 15 - den.aspects.testingInputs'.homeManager = 16 - { inputs', ... }: 17 - { 18 - home.packages = [ inputs'.nixpkgs.legacyPackages.cowsay ]; 19 - }; 20 - 21 - den.aspects.testingSelf'.homeManager = 22 - { self', ... }: 23 - { 24 - home.packages = [ self'.packages.bye ]; 25 - }; 26 - 27 - den.aspects.testingUnfree.includes = [ 28 - (den._.unfree [ "example-unfree-package" ]) 29 - { 30 - homeManager = 31 - { pkgs, ... }: 32 - { 33 - home.packages = [ pkgs.hello-unfree ]; 34 - }; 35 - } 36 - ]; 37 - 38 - # including on user was causing duplicate definitions. 39 - den.aspects.unfree-user.includes = [ 40 - den.aspects.testingInputs' 41 - den.aspects.testingSelf' 42 - den.aspects.testingUnfree 43 - ]; 44 - 45 - flake.checks.x86_64-linux = withSystem "x86_64-linux" ( 46 - { 47 - pkgs, 48 - checkCond, 49 - ... 50 - }: 51 - let 52 - host = inputs.self.nixosConfigurations.unfree-host.config; 53 - user = host.home-manager.users.unfree-user; 54 - 55 - names = map lib.getName user.home.packages; 56 - inputsCheck = builtins.elem "cowsay" names; 57 - selfCheck = builtins.elem "hello" names; 58 - 59 - useGlobalPkgs = host.home-manager.useGlobalPkgs; 60 - unfreeCheck = user.nixpkgs.config.allowUnfreePredicate pkgs.hello-unfree; 61 - in 62 - { 63 - unfree-user-has-self-bye = checkCond "self bye" selfCheck; 64 - unfree-user-has-inputs-cowsay = checkCond "inputs cowsay" inputsCheck; 65 - unfree-user-hm-unfree = checkCond "hm unfree" ((!useGlobalPkgs) && unfreeCheck); 66 - } 67 - ); 68 - 69 - perSystem = 70 - { pkgs, ... }: 71 - { 72 - packages.bye = pkgs.hello; 73 - }; 74 - }
-25
templates/ci/modules/unfree.nix
··· 1 - { den, ... }: 2 - 3 - let 4 - codeAspect = { 5 - includes = [ (den._.unfree [ "vscode" ]) ]; 6 - homeManager.programs.vscode.enable = true; 7 - }; 8 - discordAspect = { 9 - includes = [ 10 - (den._.unfree [ "discord" ]) 11 - ]; 12 - homeManager = 13 - { pkgs, ... }: 14 - { 15 - home.packages = [ pkgs.discord ]; 16 - }; 17 - }; 18 - in 19 - { 20 - # cam uses unfree vscode and discord loaded from different aspects. 21 - den.aspects.cam.includes = [ 22 - codeAspect 23 - discordAspect 24 - ]; 25 - }
-12
templates/ci/modules/user-configures-hosts.nix
··· 1 - { 2 - # Example: user provides static config to all its nixos hosts. 3 - den.aspects.alice.nixos.users.users.alice.description = "Alice Q. User"; 4 - 5 - perSystem = 6 - { checkCond, rockhopper, ... }: 7 - { 8 - checks.user-contributes-to-host = checkCond "alice.nixos sets on rockhopper host" ( 9 - rockhopper.config.users.users.alice.description == "Alice Q. User" 10 - ); 11 - }; 12 - }
-12
templates/ci/modules/user-home-defaults.nix
··· 1 - { 2 - # globally enable fish on all homes ever. 3 - den.default.homeManager.programs.fish.enable = true; 4 - 5 - perSystem = 6 - { checkCond, alice-at-rockhopper, ... }: 7 - { 8 - checks.alice-hm-fish-enabled-by-default = checkCond "home-managed fish for alice" ( 9 - alice-at-rockhopper.programs.fish.enable 10 - ); 11 - }; 12 - }
-38
templates/ci/modules/user-host-conditional-os.nix
··· 1 - { lib, ... }: 2 - let 3 - 4 - # Example: configuration that depends on both host and user. provides anytime { user, host } is in context. 5 - user-to-host-conditional = 6 - { user, host, ... }: 7 - if user.userName == "alice" && !lib.hasSuffix "darwin" host.system then 8 - { 9 - nixos.programs.tmux.enable = true; 10 - } 11 - else 12 - { }; 13 - in 14 - { 15 - 16 - # Example: user provides parametric host configuration. 17 - den.aspects.alice.includes = [ 18 - user-to-host-conditional 19 - ]; 20 - 21 - perSystem = 22 - { 23 - checkCond, 24 - rockhopper, 25 - honeycrisp, 26 - ... 27 - }: 28 - { 29 - checks.alice-os-tmux-enabled-on = checkCond "os tmux for hosts having alice" ( 30 - rockhopper.config.programs.tmux.enable 31 - ); 32 - checks.alice-os-tmux-enabled-off = checkCond "os tmux for hosts having alice" ( 33 - !honeycrisp.config.programs.tmux.enable 34 - ); 35 - 36 - }; 37 - 38 - }
-17
templates/ci/modules/user-shell.nix
··· 1 - { den, lib, ... }: 2 - { 3 - 4 - den.aspects.will.includes = [ 5 - # will has always loved red snappers 6 - (den._.user-shell "fish") 7 - ]; 8 - 9 - perSystem = 10 - { checkCond, adelie, ... }: 11 - { 12 - checks.will-always-love-you = checkCond "red-snapper fish is default shell" ( 13 - "fish" == lib.getName adelie.config.users.users.will.shell 14 - ); 15 - }; 16 - 17 - }
-13
templates/ci/modules/user-specific-hm-config.nix
··· 1 - { 2 - # Example: enable helix for alice on all its home-managed hosts. 3 - den.aspects.alice.homeManager.programs.helix.enable = true; 4 - 5 - perSystem = 6 - { checkCond, alice-at-rockhopper, ... }: 7 - { 8 - checks.alice-hm-helix-enabled-by-user = checkCond "home-managed helix for alice" ( 9 - alice-at-rockhopper.programs.helix.enable 10 - ); 11 - }; 12 - 13 - }
-16
templates/ci/modules/vm-bootable.nix
··· 1 - let 2 - # Example: A static aspect for vm installers. 3 - vm-bootable = { 4 - nixos = 5 - { modulesPath, ... }: 6 - { 7 - imports = [ (modulesPath + "/installer/cd-dvd/installation-cd-minimal.nix") ]; 8 - }; 9 - }; 10 - in 11 - { 12 - den.default.includes = [ 13 - # Example: static aspect 14 - vm-bootable 15 - ]; 16 - }
+1 -7
templates/ci/provider/modules/den.nix
··· 12 12 13 13 provider.tools._.dev._.editors = { 14 14 description = "Editor configurations from provider flake"; 15 - nixos.environment.variables.PROVIDER_EDITOR = "vim"; 15 + nixos.programs.vim.enable = true; 16 16 homeManager = 17 17 { pkgs, ... }: 18 18 { 19 19 home.packages = [ pkgs.vim ]; 20 20 }; 21 - }; 22 - 23 - provider.tools._.dev._.shells = { 24 - description = "Shell configurations from provider flake"; 25 - nixos.environment.variables.PROVIDER_SHELL = "fish"; 26 - nixos.environment.systemPackages = [ ]; 27 21 }; 28 22 }
+13 -16
templates/default/flake.lock
··· 2 2 "nodes": { 3 3 "den": { 4 4 "locked": { 5 - "lastModified": 1771153332, 6 - "narHash": "sha256-oAzd3u2CsFxJXwZ1Mak2kJuAxKJUET7+nWLGWvdq5Jw=", 5 + "lastModified": 1771364340, 6 + "narHash": "sha256-i6IoHdOqdJHjJHuTIZqPJVDn6VVOG1nyRXR70qYQej4=", 7 7 "owner": "vic", 8 8 "repo": "den", 9 - "rev": "933a84fd1e1b625eaa20e160704f83cdbf13efd9", 9 + "rev": "f8cb8c618e1680e99c165d2bf826600170abb5a2", 10 10 "type": "github" 11 11 }, 12 12 "original": { ··· 17 17 }, 18 18 "flake-aspects": { 19 19 "locked": { 20 - "lastModified": 1771325453, 21 - "narHash": "sha256-a50O/36ySKext94tOnv7ucfLD75C1aHTWP+Um0w35R0=", 20 + "lastModified": 1771395573, 21 + "narHash": "sha256-bcCOG2CW23/Eww/zULJf1xd0Shz2zS4c2AJWwLALyJ8=", 22 22 "owner": "vic", 23 23 "repo": "flake-aspects", 24 - "rev": "cb78001b60fb34b8fabb8f78b082a6cf6c8a548d", 24 + "rev": "8297f3bc41ad79b9f01d56d0dd92f7aac51bacfb", 25 25 "type": "github" 26 26 }, 27 27 "original": { ··· 102 102 }, 103 103 "nixpkgs": { 104 104 "locked": { 105 - "lastModified": 1770843696, 106 - "narHash": "sha256-LovWTGDwXhkfCOmbgLVA10bvsi/P8eDDpRudgk68HA8=", 107 - "owner": "nixos", 108 - "repo": "nixpkgs", 109 - "rev": "2343bbb58f99267223bc2aac4fc9ea301a155a16", 110 - "type": "github" 105 + "lastModified": 1771207753, 106 + "narHash": "sha256-7o+iRF++GO/gGrgrRMlnld2V/3QIzpdwMKViVkHtMEQ=", 107 + "rev": "d1c15b7d5806069da59e819999d70e1cec0760bf", 108 + "type": "tarball", 109 + "url": "https://releases.nixos.org/nixpkgs/nixpkgs-26.05pre946960.d1c15b7d5806/nixexprs.tar.xz" 111 110 }, 112 111 "original": { 113 - "owner": "nixos", 114 - "ref": "nixpkgs-unstable", 115 - "repo": "nixpkgs", 116 - "type": "github" 112 + "type": "tarball", 113 + "url": "https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.xz" 117 114 } 118 115 }, 119 116 "root": {
+1 -1
templates/default/flake.nix
··· 17 17 url = "github:nix-community/home-manager"; 18 18 }; 19 19 import-tree.url = "github:vic/import-tree"; 20 - nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; 20 + nixpkgs.url = "https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.xz"; 21 21 nixpkgs-lib.follows = "nixpkgs"; 22 22 systems.url = "github:nix-systems/default"; 23 23 };
+10
templates/default/modules/defaults.nix
··· 1 + { 2 + den.default.nixos.system.stateVersion = "25.11"; 3 + den.default.homeManager.home.stateVersion = "25.11"; 4 + 5 + # User TODO: REMOVE THIS 6 + den.aspects.tux.nixos = { 7 + boot.loader.grub.enable = false; 8 + fileSystems."/".device = "/dev/fake"; 9 + }; 10 + }
+6 -6
templates/example/flake.lock
··· 22 22 }, 23 23 "den": { 24 24 "locked": { 25 - "lastModified": 1771153332, 26 - "narHash": "sha256-oAzd3u2CsFxJXwZ1Mak2kJuAxKJUET7+nWLGWvdq5Jw=", 25 + "lastModified": 1771364340, 26 + "narHash": "sha256-i6IoHdOqdJHjJHuTIZqPJVDn6VVOG1nyRXR70qYQej4=", 27 27 "owner": "vic", 28 28 "repo": "den", 29 - "rev": "933a84fd1e1b625eaa20e160704f83cdbf13efd9", 29 + "rev": "f8cb8c618e1680e99c165d2bf826600170abb5a2", 30 30 "type": "github" 31 31 }, 32 32 "original": { ··· 37 37 }, 38 38 "flake-aspects": { 39 39 "locked": { 40 - "lastModified": 1771325453, 41 - "narHash": "sha256-a50O/36ySKext94tOnv7ucfLD75C1aHTWP+Um0w35R0=", 40 + "lastModified": 1771395573, 41 + "narHash": "sha256-bcCOG2CW23/Eww/zULJf1xd0Shz2zS4c2AJWwLALyJ8=", 42 42 "owner": "vic", 43 43 "repo": "flake-aspects", 44 - "rev": "cb78001b60fb34b8fabb8f78b082a6cf6c8a548d", 44 + "rev": "8297f3bc41ad79b9f01d56d0dd92f7aac51bacfb", 45 45 "type": "github" 46 46 }, 47 47 "original": {
-3
templates/example/modules/aspects/defaults.nix
··· 19 19 # ${user}.provides.${host} and ${host}.provides.${user} 20 20 <eg/routes> 21 21 22 - # Enable home-manager on all hosts. 23 - <den/home-manager> 24 - 25 22 # Automatically create the user on host. 26 23 <den/define-user> 27 24
+6 -6
templates/minimal/flake.lock
··· 2 2 "nodes": { 3 3 "den": { 4 4 "locked": { 5 - "lastModified": 1771153332, 6 - "narHash": "sha256-oAzd3u2CsFxJXwZ1Mak2kJuAxKJUET7+nWLGWvdq5Jw=", 5 + "lastModified": 1771364340, 6 + "narHash": "sha256-i6IoHdOqdJHjJHuTIZqPJVDn6VVOG1nyRXR70qYQej4=", 7 7 "owner": "vic", 8 8 "repo": "den", 9 - "rev": "933a84fd1e1b625eaa20e160704f83cdbf13efd9", 9 + "rev": "f8cb8c618e1680e99c165d2bf826600170abb5a2", 10 10 "type": "github" 11 11 }, 12 12 "original": { ··· 17 17 }, 18 18 "flake-aspects": { 19 19 "locked": { 20 - "lastModified": 1771325453, 21 - "narHash": "sha256-a50O/36ySKext94tOnv7ucfLD75C1aHTWP+Um0w35R0=", 20 + "lastModified": 1771395573, 21 + "narHash": "sha256-bcCOG2CW23/Eww/zULJf1xd0Shz2zS4c2AJWwLALyJ8=", 22 22 "owner": "vic", 23 23 "repo": "flake-aspects", 24 - "rev": "cb78001b60fb34b8fabb8f78b082a6cf6c8a548d", 24 + "rev": "8297f3bc41ad79b9f01d56d0dd92f7aac51bacfb", 25 25 "type": "github" 26 26 }, 27 27 "original": {
+4
templates/minimal/modules/den.nix
··· 10 10 { pkgs, ... }: 11 11 { 12 12 environment.systemPackages = [ pkgs.hello ]; 13 + 14 + # USER TODO: remove this 15 + boot.loader.grub.enable = false; 16 + fileSystems."/".device = "/dev/null"; 13 17 }; 14 18 }; 15 19
+6 -6
templates/noflake/npins/sources.json
··· 9 9 }, 10 10 "branch": "main", 11 11 "submodules": false, 12 - "revision": "933a84fd1e1b625eaa20e160704f83cdbf13efd9", 13 - "url": "https://github.com/vic/den/archive/933a84fd1e1b625eaa20e160704f83cdbf13efd9.tar.gz", 14 - "hash": "sha256-oAzd3u2CsFxJXwZ1Mak2kJuAxKJUET7+nWLGWvdq5Jw=" 12 + "revision": "f8cb8c618e1680e99c165d2bf826600170abb5a2", 13 + "url": "https://github.com/vic/den/archive/f8cb8c618e1680e99c165d2bf826600170abb5a2.tar.gz", 14 + "hash": "sha256-i6IoHdOqdJHjJHuTIZqPJVDn6VVOG1nyRXR70qYQej4=" 15 15 }, 16 16 "flake-aspects": { 17 17 "type": "Git", ··· 22 22 }, 23 23 "branch": "main", 24 24 "submodules": false, 25 - "revision": "cb78001b60fb34b8fabb8f78b082a6cf6c8a548d", 26 - "url": "https://github.com/vic/flake-aspects/archive/cb78001b60fb34b8fabb8f78b082a6cf6c8a548d.tar.gz", 27 - "hash": "sha256-a50O/36ySKext94tOnv7ucfLD75C1aHTWP+Um0w35R0=" 25 + "revision": "8297f3bc41ad79b9f01d56d0dd92f7aac51bacfb", 26 + "url": "https://github.com/vic/flake-aspects/archive/8297f3bc41ad79b9f01d56d0dd92f7aac51bacfb.tar.gz", 27 + "hash": "sha256-bcCOG2CW23/Eww/zULJf1xd0Shz2zS4c2AJWwLALyJ8=" 28 28 }, 29 29 "import-tree": { 30 30 "type": "Git",