]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
docs: overhall of the getting started section, autogenerating readable JSON schema...
authorVasek Sraier <git@vakabus.cz>
Sun, 18 Dec 2022 16:40:58 +0000 (17:40 +0100)
committerVasek Sraier <git@vakabus.cz>
Tue, 10 Jan 2023 19:20:54 +0000 (20:20 +0100)
22 files changed:
.gitignore
doc/_static/config.schema.md [new file with mode: 0644]
doc/_static/package-lock.json [new file with mode: 0644]
doc/_static/package.json [new file with mode: 0644]
doc/architecture.rst [new file with mode: 0644]
doc/conf.py
doc/config-lua.rst [moved from doc/_static/.gitignore with 100% similarity]
doc/config-schema-header.md [new file with mode: 0644]
doc/gettingstarted-config.rst
doc/gettingstarted-startup.rst
doc/index.rst
doc/legacy.rst [new file with mode: 0644]
doc/manager-api.rst
doc/manager-kresctl.rst [new file with mode: 0644]
doc/meson.build
doc/requirements.txt
doc/upgrading-to-6.rst [new file with mode: 0644]
doc/upgrading.rst
doc/usecase-internal-resolver.rst
doc/usecase-personal-resolver.rst
manager/knot_resolver_manager/utils/modeling/base_schema.py
scripts/make-doc.sh

index a138c926b7d9c0fad1f68a789560abd663f7f14d..43d8487240718baf0591d3296f2d533d0152d6f4 100644 (file)
@@ -51,7 +51,8 @@
 /doc/html
 /doc/kresd.8
 /doc/texinfo
-/doc/_static/config-schema.json
+/doc/_static/config.schema.json
+/doc/config-schema.md
 /ephemeral_key.pem
 /install-sh
 /libkres.pc
diff --git a/doc/_static/config.schema.md b/doc/_static/config.schema.md
new file mode 100644 (file)
index 0000000..8731dff
--- /dev/null
@@ -0,0 +1,185 @@
+# JSON Schema
+
+*Knot Resolver declarative configuration.*
+
+## Properties
+
+- **`version`** *(integer)*: Version of the configuration schema. By default it is the latest supported by the resolver, but couple of versions back are be supported as well. Default: `1`.
+- **`nsid`** *(['string', 'null'])*: Name Server Identifier (RFC 5001) which allows DNS clients to request resolver to send back its NSID along with the reply to a DNS request. Default: `None`.
+- **`hostname`** *(['string', 'null'])*: Internal DNS resolver hostname. Default is machine hostname. Default: `None`.
+- **`rundir`** *(string)*: Directory where the resolver can create files and which will be it's cwd. Default: `.`.
+- **`workers`**: The number of running kresd (Knot Resolver daemon) workers. If set to 'auto', it is equal to number of CPUs available. Default: `1`.
+- **`max-workers`** *(integer)*: The maximum number of workers allowed. Cannot be changed in runtime. Minimum: `1`. Default: `80`.
+- **`management`** *(object)*: Configuration of management HTTP API. Default: `{'unix_socket': './manager.sock', 'interface': None}`.
+  - **`unix-socket`** *(['string', 'null'])*: Path to unix domain socket to listen to. Default: `None`.
+  - **`interface`** *(['string', 'null'])*: IP address and port number to listen to. Default: `None`.
+- **`webmgmt`** *(['object', 'null'])*: Configuration of legacy web management endpoint. Default: `None`.
+  - **`unix-socket`** *(['string', 'null'])*: Path to unix domain socket to listen to. Default: `None`.
+  - **`interface`** *(['string', 'null'])*: IP address or interface name with port number to listen to. Default: `None`.
+  - **`tls`** *(boolean)*: Enable/disable TLS. Default: `False`.
+  - **`cert-file`** *(['string', 'null'])*: Path to certificate file. Default: `None`.
+  - **`key-file`** *(['string', 'null'])*: Path to certificate key. Default: `None`.
+- **`options`** *(object)*: Fine-tuning global parameters of DNS resolver operation. Default: `{'glue_checking': 'normal', 'qname_minimisation': True, 'query_loopback': False, 'reorder_rrset': True, 'query_case_randomization': True, 'priming': True, 'rebinding_protection': False, 'refuse_no_rd': True, 'time_jump_detection': True, 'violators_workarounds': False, 'serve_stale': False, 'prediction': False}`.
+  - **`glue-checking`** *(string)*: Glue records scrictness checking level. Must be one of: `['normal', 'strict', 'permissive']`. Default: `normal`.
+  - **`qname-minimisation`** *(boolean)*: Send minimum amount of information in recursive queries to enhance privacy. Default: `True`.
+  - **`query-loopback`** *(boolean)*: Permits queries to loopback addresses. Default: `False`.
+  - **`reorder-rrset`** *(boolean)*: Controls whether resource records within a RRSet are reordered each time it is served from the cache. Default: `True`.
+  - **`query-case-randomization`** *(boolean)*: Randomize Query Character Case. Default: `True`.
+  - **`priming`** *(boolean)*: Initializing DNS resolver cache with Priming Queries (RFC 8109). Default: `True`.
+  - **`rebinding-protection`** *(boolean)*: Protection against DNS Rebinding attack. Default: `False`.
+  - **`refuse-no-rd`** *(boolean)*: Queries without RD (recursion desired) bit set in query are answered with REFUSED. Default: `True`.
+  - **`time-jump-detection`** *(boolean)*: Detection of difference between local system time and expiration time bounds in DNSSEC signatures for '. NS' records. Default: `True`.
+  - **`violators-workarounds`** *(boolean)*: Workarounds for known DNS protocol violators. Default: `False`.
+  - **`serve-stale`** *(boolean)*: Allows using timed-out records in case DNS resolver is unable to contact upstream servers. Default: `False`.
+  - **`prediction`**: Helps keep the cache hot by prefetching expiring records and learning usage patterns and repetitive queries. Default: `False`.
+- **`network`** *(object)*: Network connections and protocols configuration. Default: `{'do_ipv4': True, 'do_ipv6': True, 'out_interface_v4': None, 'out_interface_v6': None, 'tcp_pipeline': 100, 'edns_tcp_keepalive': True, 'edns_buffer_size': {'upstream': '1232B', 'downstream': '1232B'}, 'address_renumbering': None, 'tls': {'cert_file': None, 'key_file': None, 'sticket_secret': None, 'sticket_secret_file': None, 'auto_discovery': False, 'padding': True}, 'proxy_protocol': False, 'listen': [{'interface': '127.0.0.1', 'unix_socket': None, 'port': 53, 'kind': 'dns', 'freebind': False}, {'interface': '::1', 'unix_socket': None, 'port': 53, 'kind': 'dns', 'freebind': True}]}`.
+  - **`do-ipv4`** *(boolean)*: Enable/disable using IPv4 for contacting upstream nameservers. Default: `True`.
+  - **`do-ipv6`** *(boolean)*: Enable/disable using IPv6 for contacting upstream nameservers. Default: `True`.
+  - **`out-interface-v4`** *(['string', 'null'])*: IPv4 address used to perform queries. Not set by default, which lets the OS choose any address. Default: `None`.
+  - **`out-interface-v6`** *(['string', 'null'])*: IPv6 address used to perform queries. Not set by default, which lets the OS choose any address. Default: `None`.
+  - **`tcp-pipeline`** *(integer)*: TCP pipeline limit. The number of outstanding queries that a single client connection can make in parallel. Minimum: `0`. Maximum: `65535`. Default: `100`.
+  - **`edns-tcp-keepalive`** *(boolean)*: Allows clients to discover the connection timeout. (RFC 7828). Default: `True`.
+  - **`edns-buffer-size`** *(object)*: Maximum EDNS payload size advertised in DNS packets. Different values can be configured for communication downstream (towards clients) and upstream (towards other DNS servers). Default: `{'upstream': '1232B', 'downstream': '1232B'}`.
+    - **`upstream`** *(string)*: Maximum EDNS upstream (towards other DNS servers) payload size. Default: `1232B`.
+    - **`downstream`** *(string)*: Maximum EDNS downstream (towards clients) payload size for communication. Default: `1232B`.
+  - **`address-renumbering`** *(['array', 'null'])*: Renumbers addresses in answers to different address space. Default: `None`.
+    - **Items** *(object)*: Renumbers addresses in answers to different address space.
+      - **`source`** *(string)*: Source subnet.
+      - **`destination`**: Destination address prefix.
+  - **`tls`** *(object)*: TLS configuration, also affects DNS over TLS and DNS over HTTPS. Default: `{'cert_file': None, 'key_file': None, 'sticket_secret': None, 'sticket_secret_file': None, 'auto_discovery': False, 'padding': True}`.
+    - **`cert-file`** *(['string', 'null'])*: Path to certificate file. Default: `None`.
+    - **`key-file`** *(['string', 'null'])*: Path to certificate key file. Default: `None`.
+    - **`sticket-secret`** *(['string', 'null'])*: Secret for TLS session resumption via tickets. (RFC 5077). Default: `None`.
+    - **`sticket-secret-file`** *(['string', 'null'])*: Path to file with secret for TLS session resumption via tickets. (RFC 5077). Default: `None`.
+    - **`auto-discovery`** *(boolean)*: Automatic discovery of authoritative servers supporting DNS-over-TLS. Default: `False`.
+    - **`padding`**: EDNS(0) padding of answers to queries that arrive over TLS transport. Default: `True`.
+  - **`proxy-protocol`**: PROXYv2 protocol configuration. Default: `False`.
+  - **`listen`** *(array)*: List of interfaces to listen to and its configuration. Default: `[{'interface': '127.0.0.1', 'unix_socket': None, 'port': 53, 'kind': 'dns', 'freebind': False}, {'interface': '::1', 'unix_socket': None, 'port': 53, 'kind': 'dns', 'freebind': True}]`.
+    - **Items** *(object)*: Configuration of listening interface.
+      - **`interface`**: IP address or interface name with optional port number to listen to. Default: `None`.
+      - **`unix-socket`**: Path to unix domain socket to listen to. Default: `None`.
+      - **`port`** *(['integer', 'null'])*: Port number to listen to. Minimum: `1`. Maximum: `65535`. Default: `None`.
+      - **`kind`** *(string)*: Specifies DNS query transport protocol. Must be one of: `['dns', 'xdp', 'dot', 'doh-legacy', 'doh2']`. Default: `dns`.
+      - **`freebind`** *(boolean)*: Used for binding to non-local address. Default: `False`.
+- **`static-hints`** *(object)*: Static hints for forward records (A/AAAA) and reverse records (PTR). Default: `{'ttl': None, 'nodata': True, 'etc_hosts': False, 'root_hints': None, 'root_hints_file': None, 'hints': None, 'hints_files': None}`.
+  - **`ttl`** *(['string', 'null'])*: TTL value used for records added from static hints. Default: `None`.
+  - **`nodata`** *(boolean)*: Use NODATA synthesis. NODATA will be synthesised for matching hint name, but mismatching type. Default: `True`.
+  - **`etc-hosts`** *(boolean)*: Add hints from '/etc/hosts' file. Default: `False`.
+  - **`root-hints`** *(['object', 'null'])*: Direct addition of root hints pairs (hostname, list of addresses). Can contain additional properties. Default: `None`.
+    - **Additional Properties** *(array)*
+      - **Items**
+  - **`root-hints-file`** *(['string', 'null'])*: Path to root hints in zonefile. Replaces all current root hints. Default: `None`.
+  - **`hints`** *(['object', 'null'])*: Direct addition of hints pairs (hostname, list of addresses). Can contain additional properties. Default: `None`.
+    - **Additional Properties** *(array)*
+      - **Items**
+  - **`hints-files`** *(['array', 'null'])*: Path to hints in hosts-like file. Default: `None`.
+    - **Items** *(string)*
+- **`views`** *(['object', 'null'])*: List of views and its configuration. Can contain additional properties. Default: `None`.
+  - **Additional Properties** *(object)*: Configuration parameters that allow you to create personalized policy rules and other.
+    - **`subnets`** *(['array', 'null'])*: Identifies the client based on his subnet. Default: `None`.
+      - **Items** *(string)*
+    - **`tsig`** *(['array', 'null'])*: Identifies the client based on a TSIG key name (for testing purposes, TSIG signature is not verified!). Default: `None`.
+      - **Items** *(string)*
+    - **`options`** *(['array', 'null'])*: Configuration flags for clients identified by the view. Default: `None`.
+      - **Items** *(string)*: Must be one of: `['no-minimize', 'no-ipv4', 'no-ipv6', 'tcp', 'resolved', 'await-ipv4', 'await-ipv6', 'await-cut', 'no-edns', 'cached', 'no-cache', 'expiring', 'allow_local', 'dnssec-want', 'dnssec-bogus', 'dnssec-insecure', 'dnssec-cd', 'stub', 'always-cut', 'dnssec-wexpand', 'permissive', 'strict', 'badcookie-again', 'cname', 'reorder-rr', 'trace', 'no-0x20', 'dnssec-nods', 'dnssec-optout', 'nonauth', 'forward', 'dns64-mark', 'cache-tried', 'no-ns-found', 'pkt-is-sane', 'dns64-disable']`.
+- **`slices`** *(['array', 'null'])*: Split the entire DNS namespace into distinct slices. Default: `None`.
+  - **Items** *(object)*: Split the entire DNS namespace into distinct slices.
+    - **`function`** *(string)*: Slicing function that returns index based on query. Must be one of: `['randomize-psl']`. Default: `randomize-psl`.
+    - **`views`** *(['array', 'null'])*: Use this Slice only for clients defined by views. Default: `None`.
+      - **Items** *(string)*
+    - **`actions`** *(array)*: Actions for slice.
+      - **Items** *(object)*: Configuration of policy action.
+        - **`action`** *(string)*: Policy action. Must be one of: `['pass', 'deny', 'drop', 'refuse', 'tc', 'reroute', 'answer', 'mirror', 'forward', 'stub', 'debug-always', 'debug-cache-miss', 'qtrace', 'reqtrace']`.
+        - **`message`** *(['string', 'null'])*: Deny message for 'deny' action. Default: `None`.
+        - **`reroute`** *(['array', 'null'])*: Configuration for 'reroute' action. Default: `None`.
+          - **Items** *(object)*: Renumbers addresses in answers to different address space.
+            - **`source`** *(string)*: Source subnet.
+            - **`destination`**: Destination address prefix.
+        - **`answer`** *(['object', 'null'])*: Answer definition for 'answer' action. Default: `None`.
+          - **`rtype`** *(string)*: Type of DNS resource record. Must be one of: `['A', 'A6', 'AAAA', 'AFSDB', 'ANY', 'APL', 'ATMA', 'AVC', 'AXFR', 'CAA', 'CDNSKEY', 'CDS', 'CERT', 'CNAME', 'CSYNC', 'DHCID', 'DLV', 'DNAME', 'DNSKEY', 'DOA', 'DS', 'EID', 'EUI48', 'EUI64', 'GID', 'GPOS', 'HINFO', 'HIP', 'HTTPS', 'IPSECKEY', 'ISDN', 'IXFR', 'KEY', 'KX', 'L32', 'L64', 'LOC', 'LP', 'MAILA', 'MAILB', 'MB', 'MD', 'MF', 'MG', 'MINFO', 'MR', 'MX', 'NAPTR', 'NID', 'NIMLOC', 'NINFO', 'NS', 'NSAP', 'NSAP-PTR', 'NSEC', 'NSEC3', 'NSEC3PARAM', 'NULL', 'NXT', 'OPENPGPKEY', 'OPT', 'PTR', 'PX', 'RKEY', 'RP', 'RRSIG', 'RT', 'SIG', 'SINK', 'SMIMEA', 'SOA', 'SPF', 'SRV', 'SSHFP', 'SVCB', 'TA', 'TALINK', 'TKEY', 'TLSA', 'TSIG', 'TXT', 'UID', 'UINFO', 'UNSPEC', 'URI', 'WKS', 'X25', 'ZONEMD']`.
+          - **`rdata`** *(string)*: Data of DNS resource record.
+          - **`ttl`** *(string)*: Time-to-live value for defined answer. Default: `1s`.
+          - **`nodata`** *(boolean)*: Answer with NODATA If requested type is not configured in the answer. Otherwise policy rule is ignored. Default: `False`.
+        - **`servers`**: Servers configuration for 'mirror', 'forward' and 'stub' action. Default: `None`.
+- **`policy`** *(['array', 'null'])*: List of policy rules and its configuration. Default: `None`.
+  - **Items** *(object)*: Configuration of policy rule.
+    - **`action`** *(string)*: Policy rule action. Must be one of: `['pass', 'deny', 'drop', 'refuse', 'tc', 'reroute', 'answer', 'mirror', 'forward', 'stub', 'debug-always', 'debug-cache-miss', 'qtrace', 'reqtrace']`.
+    - **`priority`** *(['integer', 'null'])*: Policy rule priority. Default: `None`.
+    - **`filter`** *(['object', 'null'])*: Query filtering configuration. Default: `None`.
+      - **`suffix`** *(['string', 'null'])*: Filter based on the suffix of the query name. Default: `None`.
+      - **`pattern`** *(['string', 'null'])*: Filter based on the pattern that match query name. Default: `None`.
+      - **`qtype`** *(['string', 'null'])*: Filter based on the DNS query type. Must be one of: `['A', 'A6', 'AAAA', 'AFSDB', 'ANY', 'APL', 'ATMA', 'AVC', 'AXFR', 'CAA', 'CDNSKEY', 'CDS', 'CERT', 'CNAME', 'CSYNC', 'DHCID', 'DLV', 'DNAME', 'DNSKEY', 'DOA', 'DS', 'EID', 'EUI48', 'EUI64', 'GID', 'GPOS', 'HINFO', 'HIP', 'HTTPS', 'IPSECKEY', 'ISDN', 'IXFR', 'KEY', 'KX', 'L32', 'L64', 'LOC', 'LP', 'MAILA', 'MAILB', 'MB', 'MD', 'MF', 'MG', 'MINFO', 'MR', 'MX', 'NAPTR', 'NID', 'NIMLOC', 'NINFO', 'NS', 'NSAP', 'NSAP-PTR', 'NSEC', 'NSEC3', 'NSEC3PARAM', 'NULL', 'NXT', 'OPENPGPKEY', 'OPT', 'PTR', 'PX', 'RKEY', 'RP', 'RRSIG', 'RT', 'SIG', 'SINK', 'SMIMEA', 'SOA', 'SPF', 'SRV', 'SSHFP', 'SVCB', 'TA', 'TALINK', 'TKEY', 'TLSA', 'TSIG', 'TXT', 'UID', 'UINFO', 'UNSPEC', 'URI', 'WKS', 'X25', 'ZONEMD']`. Default: `None`.
+    - **`views`** *(['array', 'null'])*: Use policy rule only for clients defined by views. Default: `None`.
+      - **Items** *(string)*
+    - **`options`** *(['array', 'null'])*: Configuration flags for policy rule. Default: `None`.
+      - **Items** *(string)*: Must be one of: `['no-minimize', 'no-ipv4', 'no-ipv6', 'tcp', 'resolved', 'await-ipv4', 'await-ipv6', 'await-cut', 'no-edns', 'cached', 'no-cache', 'expiring', 'allow_local', 'dnssec-want', 'dnssec-bogus', 'dnssec-insecure', 'dnssec-cd', 'stub', 'always-cut', 'dnssec-wexpand', 'permissive', 'strict', 'badcookie-again', 'cname', 'reorder-rr', 'trace', 'no-0x20', 'dnssec-nods', 'dnssec-optout', 'nonauth', 'forward', 'dns64-mark', 'cache-tried', 'no-ns-found', 'pkt-is-sane', 'dns64-disable']`.
+    - **`message`** *(['string', 'null'])*: Deny message for 'deny' action. Default: `None`.
+    - **`reroute`** *(['array', 'null'])*: Configuration for 'reroute' action. Default: `None`.
+      - **Items** *(object)*: Renumbers addresses in answers to different address space.
+        - **`source`** *(string)*: Source subnet.
+        - **`destination`**: Destination address prefix.
+    - **`answer`** *(['object', 'null'])*: Answer definition for 'answer' action. Default: `None`.
+      - **`rtype`** *(string)*: Type of DNS resource record. Must be one of: `['A', 'A6', 'AAAA', 'AFSDB', 'ANY', 'APL', 'ATMA', 'AVC', 'AXFR', 'CAA', 'CDNSKEY', 'CDS', 'CERT', 'CNAME', 'CSYNC', 'DHCID', 'DLV', 'DNAME', 'DNSKEY', 'DOA', 'DS', 'EID', 'EUI48', 'EUI64', 'GID', 'GPOS', 'HINFO', 'HIP', 'HTTPS', 'IPSECKEY', 'ISDN', 'IXFR', 'KEY', 'KX', 'L32', 'L64', 'LOC', 'LP', 'MAILA', 'MAILB', 'MB', 'MD', 'MF', 'MG', 'MINFO', 'MR', 'MX', 'NAPTR', 'NID', 'NIMLOC', 'NINFO', 'NS', 'NSAP', 'NSAP-PTR', 'NSEC', 'NSEC3', 'NSEC3PARAM', 'NULL', 'NXT', 'OPENPGPKEY', 'OPT', 'PTR', 'PX', 'RKEY', 'RP', 'RRSIG', 'RT', 'SIG', 'SINK', 'SMIMEA', 'SOA', 'SPF', 'SRV', 'SSHFP', 'SVCB', 'TA', 'TALINK', 'TKEY', 'TLSA', 'TSIG', 'TXT', 'UID', 'UINFO', 'UNSPEC', 'URI', 'WKS', 'X25', 'ZONEMD']`.
+      - **`rdata`** *(string)*: Data of DNS resource record.
+      - **`ttl`** *(string)*: Time-to-live value for defined answer. Default: `1s`.
+      - **`nodata`** *(boolean)*: Answer with NODATA If requested type is not configured in the answer. Otherwise policy rule is ignored. Default: `False`.
+    - **`servers`**: Servers configuration for 'mirror', 'forward' and 'stub' action. Default: `None`.
+- **`rpz`** *(['array', 'null'])*: List of Response Policy Zones and its configuration. Default: `None`.
+  - **Items** *(object)*: Configuration or Response Policy Zone (RPZ).
+    - **`action`** *(string)*: RPZ rule action, typically 'deny'. Must be one of: `['pass', 'deny', 'drop', 'refuse', 'tc', 'reroute', 'answer', 'mirror', 'forward', 'stub', 'debug-always', 'debug-cache-miss', 'qtrace', 'reqtrace']`.
+    - **`file`** *(string)*: Path to the RPZ zone file.
+    - **`watch`** *(boolean)*: Reload the file when it changes. Default: `True`.
+    - **`views`** *(['array', 'null'])*: Use RPZ rule only for clients defined by views. Default: `None`.
+      - **Items** *(string)*
+    - **`options`** *(['array', 'null'])*: Configuration flags for RPZ rule. Default: `None`.
+      - **Items** *(string)*: Must be one of: `['no-minimize', 'no-ipv4', 'no-ipv6', 'tcp', 'resolved', 'await-ipv4', 'await-ipv6', 'await-cut', 'no-edns', 'cached', 'no-cache', 'expiring', 'allow_local', 'dnssec-want', 'dnssec-bogus', 'dnssec-insecure', 'dnssec-cd', 'stub', 'always-cut', 'dnssec-wexpand', 'permissive', 'strict', 'badcookie-again', 'cname', 'reorder-rr', 'trace', 'no-0x20', 'dnssec-nods', 'dnssec-optout', 'nonauth', 'forward', 'dns64-mark', 'cache-tried', 'no-ns-found', 'pkt-is-sane', 'dns64-disable']`.
+    - **`message`** *(['string', 'null'])*: Deny message for 'deny' action. Default: `None`.
+- **`stub-zones`** *(['array', 'null'])*: List of Stub Zones and its configuration. Default: `None`.
+  - **Items** *(object)*: Configuration of Stub Zone.
+    - **`name`** *(string)*: Domain name of the zone.
+    - **`servers`**: IP address of Stub server.
+    - **`views`** *(['array', 'null'])*: Use this Stub Zone only for clients defined by views. Default: `None`.
+      - **Items** *(string)*
+    - **`options`** *(['array', 'null'])*: Configuration flags for Stub Zone. Default: `None`.
+      - **Items** *(string)*: Must be one of: `['no-minimize', 'no-ipv4', 'no-ipv6', 'tcp', 'resolved', 'await-ipv4', 'await-ipv6', 'await-cut', 'no-edns', 'cached', 'no-cache', 'expiring', 'allow_local', 'dnssec-want', 'dnssec-bogus', 'dnssec-insecure', 'dnssec-cd', 'stub', 'always-cut', 'dnssec-wexpand', 'permissive', 'strict', 'badcookie-again', 'cname', 'reorder-rr', 'trace', 'no-0x20', 'dnssec-nods', 'dnssec-optout', 'nonauth', 'forward', 'dns64-mark', 'cache-tried', 'no-ns-found', 'pkt-is-sane', 'dns64-disable']`.
+- **`forward-zones`** *(['array', 'null'])*: List of Forward Zones and its configuration. Default: `None`.
+  - **Items** *(object)*: Configuration of Forward Zone.
+    - **`name`** *(string)*: Domain name of the zone.
+    - **`tls`** *(boolean)*: Enable/disable TLS for Forward servers. Default: `False`.
+    - **`servers`**: IP address of Forward server.
+    - **`views`** *(['array', 'null'])*: Use this Forward Zone only for clients defined by views. Default: `None`.
+      - **Items** *(string)*
+    - **`options`** *(['array', 'null'])*: Configuration flags for Forward Zone. Default: `None`.
+      - **Items** *(string)*: Must be one of: `['no-minimize', 'no-ipv4', 'no-ipv6', 'tcp', 'resolved', 'await-ipv4', 'await-ipv6', 'await-cut', 'no-edns', 'cached', 'no-cache', 'expiring', 'allow_local', 'dnssec-want', 'dnssec-bogus', 'dnssec-insecure', 'dnssec-cd', 'stub', 'always-cut', 'dnssec-wexpand', 'permissive', 'strict', 'badcookie-again', 'cname', 'reorder-rr', 'trace', 'no-0x20', 'dnssec-nods', 'dnssec-optout', 'nonauth', 'forward', 'dns64-mark', 'cache-tried', 'no-ns-found', 'pkt-is-sane', 'dns64-disable']`.
+- **`cache`** *(object)*: DNS resolver cache configuration. Default: `{'garbage_collector': True, 'storage': '/var/cache/knot-resolver', 'size_max': '100M', 'ttl_min': '5s', 'ttl_max': '6d', 'ns_timeout': '1000ms', 'prefill': None}`.
+  - **`garbage-collector`** *(boolean)*: Automatically use garbage collector to periodically clear cache. Default: `True`.
+  - **`storage`** *(string)*: Cache storage of the DNS resolver. Default: `/var/cache/knot-resolver`.
+  - **`size-max`** *(string)*: Maximum size of the cache. Default: `100M`.
+  - **`ttl-min`** *(string)*: Minimum time-to-live for the cache entries. Default: `5s`.
+  - **`ttl-max`** *(string)*: Maximum time-to-live for the cache entries. Default: `6d`.
+  - **`ns-timeout`** *(string)*: Time interval for which a nameserver address will be ignored after determining that it does not return (useful) answers. Default: `1000ms`.
+  - **`prefill`** *(['array', 'null'])*: Prefill the cache periodically by importing zone data obtained over HTTP. Default: `None`.
+    - **Items** *(object)*: Prefill the cache periodically by importing zone data obtained over HTTP.
+      - **`origin`** *(string)*: Origin for the imported data. Cache prefilling is only supported for the root zone ('.').
+      - **`url`** *(string)*: URL of the zone data to be imported.
+      - **`refresh-interval`** *(string)*: Time interval between consecutive refreshes of the imported zone data. Default: `1d`.
+      - **`ca-file`** *(['string', 'null'])*: Path to the file containing a CA certificate bundle that is used to authenticate the HTTPS connection. Default: `None`.
+- **`dnssec`**: Disable DNSSEC, enable with defaults or set new configuration. Default: `True`.
+- **`dns64`**: Disable DNS64 (RFC 6147), enable with defaults or set new configuration. Default: `False`.
+- **`logging`** *(object)*: Logging and debugging configuration. Default: `{'level': 'notice', 'target': 'stdout', 'groups': None, 'dnssec_bogus': False, 'dnstap': False, 'debugging': {'assertion_abort': False, 'assertion_fork': '5m'}}`.
+  - **`level`** *(string)*: Global logging level. Must be one of: `['crit', 'err', 'warning', 'notice', 'info', 'debug']`. Default: `notice`.
+  - **`target`**: Global logging stream target. "from-env" uses $KRES_LOG_TARGET and defaults to "stdout". Default: `from-env`.
+  - **`groups`** *(['array', 'null'])*: List of groups for which 'debug' logging level is set. Default: `None`.
+    - **Items** *(string)*: Must be one of: `['manager', 'supervisord', 'system', 'cache', 'io', 'net', 'ta', 'tasent', 'tasign', 'taupd', 'tls', 'gnutls', 'tls_cl', 'xdp', 'zimprt', 'zscann', 'doh', 'dnssec', 'hint', 'plan', 'iterat', 'valdtr', 'resolv', 'select', 'zonecut', 'cookie', 'statis', 'rebind', 'worker', 'policy', 'daf', 'timejm', 'timesk', 'graphi', 'prefil', 'primin', 'srvstl', 'wtchdg', 'nsid', 'dnstap', 'tests', 'dotaut', 'http', 'contrl', 'module', 'devel', 'reqdbg']`.
+  - **`dnssec-bogus`** *(boolean)*: Logging a message for each DNSSEC validation failure. Default: `False`.
+  - **`dnstap`**: Logging DNS requests and responses to a unix socket. Default: `False`.
+  - **`debugging`** *(object)*: Advanced debugging parameters for kresd (Knot Resolver daemon). Default: `{'assertion_abort': False, 'assertion_fork': '5m'}`.
+    - **`assertion-abort`** *(boolean)*: Allow the process to be aborted in case it encounters a failed assertion. Default: `False`.
+    - **`assertion-fork`** *(string)*: Fork and abord child kresd process to obtain a coredump, while the parent process recovers and keeps running. Default: `5m`.
+- **`monitoring`** *(object)*: Metrics exposisition configuration (Prometheus, Graphite). Default: `{'enabled': 'lazy', 'graphite': False}`.
+  - **`enabled`** *(string)*: configures, whether statistics module will be loaded into resolver. Must be one of: `['manager-only', 'lazy', 'always']`. Default: `lazy`.
+  - **`graphite`**: optionally configures where should graphite metrics be sent to. Default: `False`.
+- **`lua`** *(object)*: Custom Lua configuration. Default: `{'script_only': False, 'script': None, 'script_file': None}`.
+  - **`script-only`** *(boolean)*: Ignore declarative configuration and use only Lua script or file defined in this section. Default: `False`.
+  - **`script`** *(['string', 'null'])*: Custom Lua configuration script. Default: `None`.
+  - **`script-file`** *(['string', 'null'])*: Path to file that contains Lua configuration script. Default: `None`.
diff --git a/doc/_static/package-lock.json b/doc/_static/package-lock.json
new file mode 100644 (file)
index 0000000..eb5f9fb
--- /dev/null
@@ -0,0 +1,2484 @@
+{
+  "name": "_static",
+  "lockfileVersion": 2,
+  "requires": true,
+  "packages": {
+    "": {
+      "dependencies": {
+        "@adobe/jsonschema2md": "^7.1.5"
+      }
+    },
+    "node_modules/@adobe/helix-log": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/@adobe/helix-log/-/helix-log-6.0.0.tgz",
+      "integrity": "sha512-+9gpf49sFDmZLV3gtjY+RmEUistqYJdVWpiqlRYpxE59x5bHFzYf93dZ7fljSTBtZdVq8lm97HxrTUloh5HvRg==",
+      "dependencies": {
+        "big.js": "^6.1.1",
+        "colorette": "^2.0.2",
+        "ferrum": "^1.9.3",
+        "phin": "^3.6.0",
+        "polka": "^0.5.2"
+      }
+    },
+    "node_modules/@adobe/jsonschema2md": {
+      "version": "7.1.5",
+      "resolved": "https://registry.npmjs.org/@adobe/jsonschema2md/-/jsonschema2md-7.1.5.tgz",
+      "integrity": "sha512-uybF3Ryn0xz5lzGz6sb6Th5nkX9H60zOnKVYCUXunUtWENGb7Ut+8CYPzPA9sjY8+gLK8pQq3rbmsKprcjkN0A==",
+      "dependencies": {
+        "@adobe/helix-log": "6.0.0",
+        "@types/json-schema": "^7.0.8",
+        "@types/mdast": "^3.0.4",
+        "es2015-i18n-tag": "1.6.1",
+        "ferrum": "1.9.4",
+        "fs-extra": "11.1.0",
+        "github-slugger": "2.0.0",
+        "js-yaml": "4.1.0",
+        "json-schema": "^0.4.0",
+        "mdast-builder": "1.1.1",
+        "mdast-util-to-string": "3.1.0",
+        "readdirp": "3.6.0",
+        "remark-gfm": "^3.0.0",
+        "remark-parse": "10.0.1",
+        "remark-stringify": "10.0.2",
+        "unified": "10.1.2",
+        "unist-util-inspect": "7.0.1",
+        "yargs": "17.6.2"
+      },
+      "bin": {
+        "jsonschema2md": "cli.js"
+      },
+      "engines": {
+        "node": ">= 14.0.0"
+      }
+    },
+    "node_modules/@arr/every": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@arr/every/-/every-1.0.1.tgz",
+      "integrity": "sha512-UQFQ6SgyJ6LX42W8rHCs8KVc0JS0tzVL9ct4XYedJukskYVWTo49tNiMEK9C2HTyarbNiT/RVIRSY82vH+6sTg==",
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/@polka/url": {
+      "version": "0.5.0",
+      "resolved": "https://registry.npmjs.org/@polka/url/-/url-0.5.0.tgz",
+      "integrity": "sha512-oZLYFEAzUKyi3SKnXvj32ZCEGH6RDnao7COuCVhDydMS9NrCSVXhM79VaKyP5+Zc33m0QXEd2DN3UkU7OsHcfw=="
+    },
+    "node_modules/@types/debug": {
+      "version": "4.1.7",
+      "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz",
+      "integrity": "sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==",
+      "dependencies": {
+        "@types/ms": "*"
+      }
+    },
+    "node_modules/@types/json-schema": {
+      "version": "7.0.11",
+      "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
+      "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ=="
+    },
+    "node_modules/@types/mdast": {
+      "version": "3.0.10",
+      "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.10.tgz",
+      "integrity": "sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==",
+      "dependencies": {
+        "@types/unist": "*"
+      }
+    },
+    "node_modules/@types/ms": {
+      "version": "0.7.31",
+      "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz",
+      "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA=="
+    },
+    "node_modules/@types/unist": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz",
+      "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ=="
+    },
+    "node_modules/ansi-regex": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/ansi-styles": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+      "dependencies": {
+        "color-convert": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+      }
+    },
+    "node_modules/argparse": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+      "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
+    },
+    "node_modules/bail": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz",
+      "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "node_modules/big.js": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/big.js/-/big.js-6.2.1.tgz",
+      "integrity": "sha512-bCtHMwL9LeDIozFn+oNhhFoq+yQ3BNdnsLSASUxLciOb1vgvpHsIO1dsENiGMgbb4SkP5TrzWzRiLddn8ahVOQ==",
+      "engines": {
+        "node": "*"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/bigjs"
+      }
+    },
+    "node_modules/ccount": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz",
+      "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "node_modules/centra": {
+      "version": "2.6.0",
+      "resolved": "https://registry.npmjs.org/centra/-/centra-2.6.0.tgz",
+      "integrity": "sha512-dgh+YleemrT8u85QL11Z6tYhegAs3MMxsaWAq/oXeAmYJ7VxL3SI9TZtnfaEvNDMAPolj25FXIb3S+HCI4wQaQ=="
+    },
+    "node_modules/character-entities": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz",
+      "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "node_modules/cliui": {
+      "version": "8.0.1",
+      "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+      "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
+      "dependencies": {
+        "string-width": "^4.2.0",
+        "strip-ansi": "^6.0.1",
+        "wrap-ansi": "^7.0.0"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/color-convert": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+      "dependencies": {
+        "color-name": "~1.1.4"
+      },
+      "engines": {
+        "node": ">=7.0.0"
+      }
+    },
+    "node_modules/color-name": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+    },
+    "node_modules/colorette": {
+      "version": "2.0.19",
+      "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz",
+      "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ=="
+    },
+    "node_modules/cuint": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/cuint/-/cuint-0.2.2.tgz",
+      "integrity": "sha512-d4ZVpCW31eWwCMe1YT3ur7mUDnTXbgwyzaL320DrcRT45rfjYxkt5QWLrmOJ+/UEAI2+fQgKe/fCjR8l4TpRgw=="
+    },
+    "node_modules/debug": {
+      "version": "4.3.4",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+      "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+      "dependencies": {
+        "ms": "2.1.2"
+      },
+      "engines": {
+        "node": ">=6.0"
+      },
+      "peerDependenciesMeta": {
+        "supports-color": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/decode-named-character-reference": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz",
+      "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==",
+      "dependencies": {
+        "character-entities": "^2.0.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "node_modules/dequal": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
+      "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/diff": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz",
+      "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==",
+      "engines": {
+        "node": ">=0.3.1"
+      }
+    },
+    "node_modules/emoji-regex": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
+    },
+    "node_modules/es2015-i18n-tag": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/es2015-i18n-tag/-/es2015-i18n-tag-1.6.1.tgz",
+      "integrity": "sha512-MYoh9p+JTkgnzBh0MEBON6xUyzdmwT6wzsmmFJvZujGSXiI2kM+3XvFl6+AcIO2eeL6VWgtX9szSiDTMwDxyYA==",
+      "engines": {
+        "node": ">= 4.0.0"
+      }
+    },
+    "node_modules/escalade": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+      "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/escape-string-regexp": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz",
+      "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/extend": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+      "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
+    },
+    "node_modules/fastestsmallesttextencoderdecoder": {
+      "version": "1.0.22",
+      "resolved": "https://registry.npmjs.org/fastestsmallesttextencoderdecoder/-/fastestsmallesttextencoderdecoder-1.0.22.tgz",
+      "integrity": "sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw=="
+    },
+    "node_modules/ferrum": {
+      "version": "1.9.4",
+      "resolved": "https://registry.npmjs.org/ferrum/-/ferrum-1.9.4.tgz",
+      "integrity": "sha512-ooNerLoIht/dK4CQJux93z/hnt9JysrXniJCI3r6YRgmHeXC57EJ8XaTCT1Gm8LfhIAeWxyJA0O7d/W3pqDYRg==",
+      "dependencies": {
+        "fastestsmallesttextencoderdecoder": "1.0.22",
+        "lodash.isplainobject": "4.0.6",
+        "xxhashjs": "0.2.2"
+      }
+    },
+    "node_modules/fs-extra": {
+      "version": "11.1.0",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.0.tgz",
+      "integrity": "sha512-0rcTq621PD5jM/e0a3EJoGC/1TC5ZBCERW82LQuwfGnCa1V8w7dpYH1yNu+SLb6E5dkeCBzKEyLGlFrnr+dUyw==",
+      "dependencies": {
+        "graceful-fs": "^4.2.0",
+        "jsonfile": "^6.0.1",
+        "universalify": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=14.14"
+      }
+    },
+    "node_modules/get-caller-file": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+      "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+      "engines": {
+        "node": "6.* || 8.* || >= 10.*"
+      }
+    },
+    "node_modules/github-slugger": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz",
+      "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw=="
+    },
+    "node_modules/graceful-fs": {
+      "version": "4.2.10",
+      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
+      "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA=="
+    },
+    "node_modules/is-buffer": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz",
+      "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/is-fullwidth-code-point": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/is-plain-obj": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz",
+      "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/js-yaml": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+      "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+      "dependencies": {
+        "argparse": "^2.0.1"
+      },
+      "bin": {
+        "js-yaml": "bin/js-yaml.js"
+      }
+    },
+    "node_modules/json-schema": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
+      "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="
+    },
+    "node_modules/jsonfile": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
+      "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+      "dependencies": {
+        "universalify": "^2.0.0"
+      },
+      "optionalDependencies": {
+        "graceful-fs": "^4.1.6"
+      }
+    },
+    "node_modules/kleur": {
+      "version": "4.1.5",
+      "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
+      "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==",
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/lodash.isplainobject": {
+      "version": "4.0.6",
+      "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
+      "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="
+    },
+    "node_modules/longest-streak": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz",
+      "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "node_modules/markdown-table": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz",
+      "integrity": "sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "node_modules/matchit": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/matchit/-/matchit-1.1.0.tgz",
+      "integrity": "sha512-+nGYoOlfHmxe5BW5tE0EMJppXEwdSf8uBA1GTZC7Q77kbT35+VKLYJMzVNWCHSsga1ps1tPYFtFyvxvKzWVmMA==",
+      "dependencies": {
+        "@arr/every": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/mdast-builder": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/mdast-builder/-/mdast-builder-1.1.1.tgz",
+      "integrity": "sha512-a3KBk/LmYD6wKsWi8WJrGU/rXR4yuF4Men0JO0z6dSZCm5FrXXWTRDjqK0vGSqa+1M6p9edeuypZAZAzSehTUw==",
+      "dependencies": {
+        "@types/unist": "^2.0.3"
+      }
+    },
+    "node_modules/mdast-util-find-and-replace": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-2.2.1.tgz",
+      "integrity": "sha512-SobxkQXFAdd4b5WmEakmkVoh18icjQRxGy5OWTCzgsLRm1Fu/KCtwD1HIQSsmq5ZRjVH0Ehwg6/Fn3xIUk+nKw==",
+      "dependencies": {
+        "escape-string-regexp": "^5.0.0",
+        "unist-util-is": "^5.0.0",
+        "unist-util-visit-parents": "^5.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/mdast-util-from-markdown": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.2.0.tgz",
+      "integrity": "sha512-iZJyyvKD1+K7QX1b5jXdE7Sc5dtoTry1vzV28UZZe8Z1xVnB/czKntJ7ZAkG0tANqRnBF6p3p7GpU1y19DTf2Q==",
+      "dependencies": {
+        "@types/mdast": "^3.0.0",
+        "@types/unist": "^2.0.0",
+        "decode-named-character-reference": "^1.0.0",
+        "mdast-util-to-string": "^3.1.0",
+        "micromark": "^3.0.0",
+        "micromark-util-decode-numeric-character-reference": "^1.0.0",
+        "micromark-util-decode-string": "^1.0.0",
+        "micromark-util-normalize-identifier": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0",
+        "unist-util-stringify-position": "^3.0.0",
+        "uvu": "^0.5.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/mdast-util-gfm": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-2.0.1.tgz",
+      "integrity": "sha512-42yHBbfWIFisaAfV1eixlabbsa6q7vHeSPY+cg+BBjX51M8xhgMacqH9g6TftB/9+YkcI0ooV4ncfrJslzm/RQ==",
+      "dependencies": {
+        "mdast-util-from-markdown": "^1.0.0",
+        "mdast-util-gfm-autolink-literal": "^1.0.0",
+        "mdast-util-gfm-footnote": "^1.0.0",
+        "mdast-util-gfm-strikethrough": "^1.0.0",
+        "mdast-util-gfm-table": "^1.0.0",
+        "mdast-util-gfm-task-list-item": "^1.0.0",
+        "mdast-util-to-markdown": "^1.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/mdast-util-gfm-autolink-literal": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-1.0.2.tgz",
+      "integrity": "sha512-FzopkOd4xTTBeGXhXSBU0OCDDh5lUj2rd+HQqG92Ld+jL4lpUfgX2AT2OHAVP9aEeDKp7G92fuooSZcYJA3cRg==",
+      "dependencies": {
+        "@types/mdast": "^3.0.0",
+        "ccount": "^2.0.0",
+        "mdast-util-find-and-replace": "^2.0.0",
+        "micromark-util-character": "^1.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/mdast-util-gfm-footnote": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-1.0.1.tgz",
+      "integrity": "sha512-p+PrYlkw9DeCRkTVw1duWqPRHX6Ywh2BNKJQcZbCwAuP/59B0Lk9kakuAd7KbQprVO4GzdW8eS5++A9PUSqIyw==",
+      "dependencies": {
+        "@types/mdast": "^3.0.0",
+        "mdast-util-to-markdown": "^1.3.0",
+        "micromark-util-normalize-identifier": "^1.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/mdast-util-gfm-strikethrough": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-1.0.2.tgz",
+      "integrity": "sha512-T/4DVHXcujH6jx1yqpcAYYwd+z5lAYMw4Ls6yhTfbMMtCt0PHY4gEfhW9+lKsLBtyhUGKRIzcUA2FATVqnvPDA==",
+      "dependencies": {
+        "@types/mdast": "^3.0.0",
+        "mdast-util-to-markdown": "^1.3.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/mdast-util-gfm-table": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-1.0.6.tgz",
+      "integrity": "sha512-uHR+fqFq3IvB3Rd4+kzXW8dmpxUhvgCQZep6KdjsLK4O6meK5dYZEayLtIxNus1XO3gfjfcIFe8a7L0HZRGgag==",
+      "dependencies": {
+        "@types/mdast": "^3.0.0",
+        "markdown-table": "^3.0.0",
+        "mdast-util-from-markdown": "^1.0.0",
+        "mdast-util-to-markdown": "^1.3.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/mdast-util-gfm-task-list-item": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-1.0.1.tgz",
+      "integrity": "sha512-KZ4KLmPdABXOsfnM6JHUIjxEvcx2ulk656Z/4Balw071/5qgnhz+H1uGtf2zIGnrnvDC8xR4Fj9uKbjAFGNIeA==",
+      "dependencies": {
+        "@types/mdast": "^3.0.0",
+        "mdast-util-to-markdown": "^1.3.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/mdast-util-to-markdown": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.4.0.tgz",
+      "integrity": "sha512-IjXARf/O8VGx/pc5SZ7syfydq1DYL9vd92orsG5U0b4GNCmAvXzu+n7sbzfIKrXwB0AVrYk3NV2kXl0AIi9LCA==",
+      "dependencies": {
+        "@types/mdast": "^3.0.0",
+        "@types/unist": "^2.0.0",
+        "longest-streak": "^3.0.0",
+        "mdast-util-to-string": "^3.0.0",
+        "micromark-util-decode-string": "^1.0.0",
+        "unist-util-visit": "^4.0.0",
+        "zwitch": "^2.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/mdast-util-to-string": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.1.0.tgz",
+      "integrity": "sha512-n4Vypz/DZgwo0iMHLQL49dJzlp7YtAJP+N07MZHpjPf/5XJuHUWstviF4Mn2jEiR/GNmtnRRqnwsXExk3igfFA==",
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/micromark": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.1.0.tgz",
+      "integrity": "sha512-6Mj0yHLdUZjHnOPgr5xfWIMqMWS12zDN6iws9SLuSz76W8jTtAv24MN4/CL7gJrl5vtxGInkkqDv/JIoRsQOvA==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "@types/debug": "^4.0.0",
+        "debug": "^4.0.0",
+        "decode-named-character-reference": "^1.0.0",
+        "micromark-core-commonmark": "^1.0.1",
+        "micromark-factory-space": "^1.0.0",
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-chunked": "^1.0.0",
+        "micromark-util-combine-extensions": "^1.0.0",
+        "micromark-util-decode-numeric-character-reference": "^1.0.0",
+        "micromark-util-encode": "^1.0.0",
+        "micromark-util-normalize-identifier": "^1.0.0",
+        "micromark-util-resolve-all": "^1.0.0",
+        "micromark-util-sanitize-uri": "^1.0.0",
+        "micromark-util-subtokenize": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.1",
+        "uvu": "^0.5.0"
+      }
+    },
+    "node_modules/micromark-core-commonmark": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.0.6.tgz",
+      "integrity": "sha512-K+PkJTxqjFfSNkfAhp4GB+cZPfQd6dxtTXnf+RjZOV7T4EEXnvgzOcnp+eSTmpGk9d1S9sL6/lqrgSNn/s0HZA==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "decode-named-character-reference": "^1.0.0",
+        "micromark-factory-destination": "^1.0.0",
+        "micromark-factory-label": "^1.0.0",
+        "micromark-factory-space": "^1.0.0",
+        "micromark-factory-title": "^1.0.0",
+        "micromark-factory-whitespace": "^1.0.0",
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-chunked": "^1.0.0",
+        "micromark-util-classify-character": "^1.0.0",
+        "micromark-util-html-tag-name": "^1.0.0",
+        "micromark-util-normalize-identifier": "^1.0.0",
+        "micromark-util-resolve-all": "^1.0.0",
+        "micromark-util-subtokenize": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.1",
+        "uvu": "^0.5.0"
+      }
+    },
+    "node_modules/micromark-extension-gfm": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-2.0.1.tgz",
+      "integrity": "sha512-p2sGjajLa0iYiGQdT0oelahRYtMWvLjy8J9LOCxzIQsllMCGLbsLW+Nc+N4vi02jcRJvedVJ68cjelKIO6bpDA==",
+      "dependencies": {
+        "micromark-extension-gfm-autolink-literal": "^1.0.0",
+        "micromark-extension-gfm-footnote": "^1.0.0",
+        "micromark-extension-gfm-strikethrough": "^1.0.0",
+        "micromark-extension-gfm-table": "^1.0.0",
+        "micromark-extension-gfm-tagfilter": "^1.0.0",
+        "micromark-extension-gfm-task-list-item": "^1.0.0",
+        "micromark-util-combine-extensions": "^1.0.0",
+        "micromark-util-types": "^1.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/micromark-extension-gfm-autolink-literal": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-1.0.3.tgz",
+      "integrity": "sha512-i3dmvU0htawfWED8aHMMAzAVp/F0Z+0bPh3YrbTPPL1v4YAlCZpy5rBO5p0LPYiZo0zFVkoYh7vDU7yQSiCMjg==",
+      "dependencies": {
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-sanitize-uri": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0",
+        "uvu": "^0.5.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/micromark-extension-gfm-footnote": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-1.0.4.tgz",
+      "integrity": "sha512-E/fmPmDqLiMUP8mLJ8NbJWJ4bTw6tS+FEQS8CcuDtZpILuOb2kjLqPEeAePF1djXROHXChM/wPJw0iS4kHCcIg==",
+      "dependencies": {
+        "micromark-core-commonmark": "^1.0.0",
+        "micromark-factory-space": "^1.0.0",
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-normalize-identifier": "^1.0.0",
+        "micromark-util-sanitize-uri": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0",
+        "uvu": "^0.5.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/micromark-extension-gfm-strikethrough": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-1.0.4.tgz",
+      "integrity": "sha512-/vjHU/lalmjZCT5xt7CcHVJGq8sYRm80z24qAKXzaHzem/xsDYb2yLL+NNVbYvmpLx3O7SYPuGL5pzusL9CLIQ==",
+      "dependencies": {
+        "micromark-util-chunked": "^1.0.0",
+        "micromark-util-classify-character": "^1.0.0",
+        "micromark-util-resolve-all": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0",
+        "uvu": "^0.5.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/micromark-extension-gfm-table": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-1.0.5.tgz",
+      "integrity": "sha512-xAZ8J1X9W9K3JTJTUL7G6wSKhp2ZYHrFk5qJgY/4B33scJzE2kpfRL6oiw/veJTbt7jiM/1rngLlOKPWr1G+vg==",
+      "dependencies": {
+        "micromark-factory-space": "^1.0.0",
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0",
+        "uvu": "^0.5.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/micromark-extension-gfm-tagfilter": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-1.0.1.tgz",
+      "integrity": "sha512-Ty6psLAcAjboRa/UKUbbUcwjVAv5plxmpUTy2XC/3nJFL37eHej8jrHrRzkqcpipJliuBH30DTs7+3wqNcQUVA==",
+      "dependencies": {
+        "micromark-util-types": "^1.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/micromark-extension-gfm-task-list-item": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-1.0.3.tgz",
+      "integrity": "sha512-PpysK2S1Q/5VXi72IIapbi/jliaiOFzv7THH4amwXeYXLq3l1uo8/2Be0Ac1rEwK20MQEsGH2ltAZLNY2KI/0Q==",
+      "dependencies": {
+        "micromark-factory-space": "^1.0.0",
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0",
+        "uvu": "^0.5.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/micromark-factory-destination": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.0.0.tgz",
+      "integrity": "sha512-eUBA7Rs1/xtTVun9TmV3gjfPz2wEwgK5R5xcbIM5ZYAtvGF6JkyaDsj0agx8urXnO31tEO6Ug83iVH3tdedLnw==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0"
+      }
+    },
+    "node_modules/micromark-factory-label": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.0.2.tgz",
+      "integrity": "sha512-CTIwxlOnU7dEshXDQ+dsr2n+yxpP0+fn271pu0bwDIS8uqfFcumXpj5mLn3hSC8iw2MUr6Gx8EcKng1dD7i6hg==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0",
+        "uvu": "^0.5.0"
+      }
+    },
+    "node_modules/micromark-factory-space": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.0.0.tgz",
+      "integrity": "sha512-qUmqs4kj9a5yBnk3JMLyjtWYN6Mzfcx8uJfi5XAveBniDevmZasdGBba5b4QsvRcAkmvGo5ACmSUmyGiKTLZew==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-types": "^1.0.0"
+      }
+    },
+    "node_modules/micromark-factory-title": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.0.2.tgz",
+      "integrity": "sha512-zily+Nr4yFqgMGRKLpTVsNl5L4PMu485fGFDOQJQBl2NFpjGte1e86zC0da93wf97jrc4+2G2GQudFMHn3IX+A==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "micromark-factory-space": "^1.0.0",
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0",
+        "uvu": "^0.5.0"
+      }
+    },
+    "node_modules/micromark-factory-whitespace": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.0.0.tgz",
+      "integrity": "sha512-Qx7uEyahU1lt1RnsECBiuEbfr9INjQTGa6Err+gF3g0Tx4YEviPbqqGKNv/NrBaE7dVHdn1bVZKM/n5I/Bak7A==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "micromark-factory-space": "^1.0.0",
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0"
+      }
+    },
+    "node_modules/micromark-util-character": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.1.0.tgz",
+      "integrity": "sha512-agJ5B3unGNJ9rJvADMJ5ZiYjBRyDpzKAOk01Kpi1TKhlT1APx3XZk6eN7RtSz1erbWHC2L8T3xLZ81wdtGRZzg==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0"
+      }
+    },
+    "node_modules/micromark-util-chunked": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.0.0.tgz",
+      "integrity": "sha512-5e8xTis5tEZKgesfbQMKRCyzvffRRUX+lK/y+DvsMFdabAicPkkZV6gO+FEWi9RfuKKoxxPwNL+dFF0SMImc1g==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "micromark-util-symbol": "^1.0.0"
+      }
+    },
+    "node_modules/micromark-util-classify-character": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.0.0.tgz",
+      "integrity": "sha512-F8oW2KKrQRb3vS5ud5HIqBVkCqQi224Nm55o5wYLzY/9PwHGXC01tr3d7+TqHHz6zrKQ72Okwtvm/xQm6OVNZA==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0"
+      }
+    },
+    "node_modules/micromark-util-combine-extensions": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.0.0.tgz",
+      "integrity": "sha512-J8H058vFBdo/6+AsjHp2NF7AJ02SZtWaVUjsayNFeAiydTxUwViQPxN0Hf8dp4FmCQi0UUFovFsEyRSUmFH3MA==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "micromark-util-chunked": "^1.0.0",
+        "micromark-util-types": "^1.0.0"
+      }
+    },
+    "node_modules/micromark-util-decode-numeric-character-reference": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.0.0.tgz",
+      "integrity": "sha512-OzO9AI5VUtrTD7KSdagf4MWgHMtET17Ua1fIpXTpuhclCqD8egFWo85GxSGvxgkGS74bEahvtM0WP0HjvV0e4w==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "micromark-util-symbol": "^1.0.0"
+      }
+    },
+    "node_modules/micromark-util-decode-string": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.0.2.tgz",
+      "integrity": "sha512-DLT5Ho02qr6QWVNYbRZ3RYOSSWWFuH3tJexd3dgN1odEuPNxCngTCXJum7+ViRAd9BbdxCvMToPOD/IvVhzG6Q==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "decode-named-character-reference": "^1.0.0",
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-decode-numeric-character-reference": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0"
+      }
+    },
+    "node_modules/micromark-util-encode": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.0.1.tgz",
+      "integrity": "sha512-U2s5YdnAYexjKDel31SVMPbfi+eF8y1U4pfiRW/Y8EFVCy/vgxk/2wWTxzcqE71LHtCuCzlBDRU2a5CQ5j+mQA==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ]
+    },
+    "node_modules/micromark-util-html-tag-name": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.1.0.tgz",
+      "integrity": "sha512-BKlClMmYROy9UiV03SwNmckkjn8QHVaWkqoAqzivabvdGcwNGMMMH/5szAnywmsTBUzDsU57/mFi0sp4BQO6dA==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ]
+    },
+    "node_modules/micromark-util-normalize-identifier": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.0.0.tgz",
+      "integrity": "sha512-yg+zrL14bBTFrQ7n35CmByWUTFsgst5JhA4gJYoty4Dqzj4Z4Fr/DHekSS5aLfH9bdlfnSvKAWsAgJhIbogyBg==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "micromark-util-symbol": "^1.0.0"
+      }
+    },
+    "node_modules/micromark-util-resolve-all": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.0.0.tgz",
+      "integrity": "sha512-CB/AGk98u50k42kvgaMM94wzBqozSzDDaonKU7P7jwQIuH2RU0TeBqGYJz2WY1UdihhjweivStrJ2JdkdEmcfw==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "micromark-util-types": "^1.0.0"
+      }
+    },
+    "node_modules/micromark-util-sanitize-uri": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.1.0.tgz",
+      "integrity": "sha512-RoxtuSCX6sUNtxhbmsEFQfWzs8VN7cTctmBPvYivo98xb/kDEoTCtJQX5wyzIYEmk/lvNFTat4hL8oW0KndFpg==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-encode": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0"
+      }
+    },
+    "node_modules/micromark-util-subtokenize": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.0.2.tgz",
+      "integrity": "sha512-d90uqCnXp/cy4G881Ub4psE57Sf8YD0pim9QdjCRNjfas2M1u6Lbt+XZK9gnHL2XFhnozZiEdCa9CNfXSfQ6xA==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "micromark-util-chunked": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0",
+        "uvu": "^0.5.0"
+      }
+    },
+    "node_modules/micromark-util-symbol": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.0.1.tgz",
+      "integrity": "sha512-oKDEMK2u5qqAptasDAwWDXq0tG9AssVwAx3E9bBF3t/shRIGsWIRG+cGafs2p/SnDSOecnt6hZPCE2o6lHfFmQ==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ]
+    },
+    "node_modules/micromark-util-types": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.0.2.tgz",
+      "integrity": "sha512-DCfg/T8fcrhrRKTPjRrw/5LLvdGV7BHySf/1LOZx7TzWZdYRjogNtyNq885z3nNallwr3QUKARjqvHqX1/7t+w==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ]
+    },
+    "node_modules/mri": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
+      "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==",
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ms": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+    },
+    "node_modules/phin": {
+      "version": "3.7.0",
+      "resolved": "https://registry.npmjs.org/phin/-/phin-3.7.0.tgz",
+      "integrity": "sha512-DqnVNrpYhKGBZppNKprD+UJylMeEKOZxHgPB+ZP6mGzf3uA2uox4Ep9tUm+rUc8WLIdHT3HcAE4X8fhwQA9JKg==",
+      "dependencies": {
+        "centra": "^2.6.0"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/picomatch": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+      "engines": {
+        "node": ">=8.6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/jonschlinkert"
+      }
+    },
+    "node_modules/polka": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/polka/-/polka-0.5.2.tgz",
+      "integrity": "sha512-FVg3vDmCqP80tOrs+OeNlgXYmFppTXdjD5E7I4ET1NjvtNmQrb1/mJibybKkb/d4NA7YWAr1ojxuhpL3FHqdlw==",
+      "dependencies": {
+        "@polka/url": "^0.5.0",
+        "trouter": "^2.0.1"
+      }
+    },
+    "node_modules/readdirp": {
+      "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+      "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+      "dependencies": {
+        "picomatch": "^2.2.1"
+      },
+      "engines": {
+        "node": ">=8.10.0"
+      }
+    },
+    "node_modules/remark-gfm": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-3.0.1.tgz",
+      "integrity": "sha512-lEFDoi2PICJyNrACFOfDD3JlLkuSbOa5Wd8EPt06HUdptv8Gn0bxYTdbU/XXQ3swAPkEaGxxPN9cbnMHvVu1Ig==",
+      "dependencies": {
+        "@types/mdast": "^3.0.0",
+        "mdast-util-gfm": "^2.0.0",
+        "micromark-extension-gfm": "^2.0.0",
+        "unified": "^10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/remark-parse": {
+      "version": "10.0.1",
+      "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-10.0.1.tgz",
+      "integrity": "sha512-1fUyHr2jLsVOkhbvPRBJ5zTKZZyD6yZzYaWCS6BPBdQ8vEMBCH+9zNCDA6tET/zHCi/jLqjCWtlJZUPk+DbnFw==",
+      "dependencies": {
+        "@types/mdast": "^3.0.0",
+        "mdast-util-from-markdown": "^1.0.0",
+        "unified": "^10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/remark-stringify": {
+      "version": "10.0.2",
+      "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-10.0.2.tgz",
+      "integrity": "sha512-6wV3pvbPvHkbNnWB0wdDvVFHOe1hBRAx1Q/5g/EpH4RppAII6J8Gnwe7VbHuXaoKIF6LAg6ExTel/+kNqSQ7lw==",
+      "dependencies": {
+        "@types/mdast": "^3.0.0",
+        "mdast-util-to-markdown": "^1.0.0",
+        "unified": "^10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/require-directory": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+      "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/sade": {
+      "version": "1.8.1",
+      "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz",
+      "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==",
+      "dependencies": {
+        "mri": "^1.1.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/string-width": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+      "dependencies": {
+        "emoji-regex": "^8.0.0",
+        "is-fullwidth-code-point": "^3.0.0",
+        "strip-ansi": "^6.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/strip-ansi": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+      "dependencies": {
+        "ansi-regex": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/trough": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/trough/-/trough-2.1.0.tgz",
+      "integrity": "sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "node_modules/trouter": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/trouter/-/trouter-2.0.1.tgz",
+      "integrity": "sha512-kr8SKKw94OI+xTGOkfsvwZQ8mWoikZDd2n8XZHjJVZUARZT+4/VV6cacRS6CLsH9bNm+HFIPU1Zx4CnNnb4qlQ==",
+      "dependencies": {
+        "matchit": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/unified": {
+      "version": "10.1.2",
+      "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz",
+      "integrity": "sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==",
+      "dependencies": {
+        "@types/unist": "^2.0.0",
+        "bail": "^2.0.0",
+        "extend": "^3.0.0",
+        "is-buffer": "^2.0.0",
+        "is-plain-obj": "^4.0.0",
+        "trough": "^2.0.0",
+        "vfile": "^5.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/unist-util-inspect": {
+      "version": "7.0.1",
+      "resolved": "https://registry.npmjs.org/unist-util-inspect/-/unist-util-inspect-7.0.1.tgz",
+      "integrity": "sha512-gEPeSrsYXus8012VJ00p9uZC8D0iogtLLiHlBgvS61hU22KNKduQhMKezJm83viHlLf3TYS2y9SDEFglWPDMKw==",
+      "dependencies": {
+        "@types/unist": "^2.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/unist-util-is": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz",
+      "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==",
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/unist-util-stringify-position": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.2.tgz",
+      "integrity": "sha512-7A6eiDCs9UtjcwZOcCpM4aPII3bAAGv13E96IkawkOAW0OhH+yRxtY0lzo8KiHpzEMfH7Q+FizUmwp8Iqy5EWg==",
+      "dependencies": {
+        "@types/unist": "^2.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/unist-util-visit": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.1.tgz",
+      "integrity": "sha512-n9KN3WV9k4h1DxYR1LoajgN93wpEi/7ZplVe02IoB4gH5ctI1AaF2670BLHQYbwj+pY83gFtyeySFiyMHJklrg==",
+      "dependencies": {
+        "@types/unist": "^2.0.0",
+        "unist-util-is": "^5.0.0",
+        "unist-util-visit-parents": "^5.1.1"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/unist-util-visit-parents": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.1.tgz",
+      "integrity": "sha512-gks4baapT/kNRaWxuGkl5BIhoanZo7sC/cUT/JToSRNL1dYoXRFl75d++NkjYk4TAu2uv2Px+l8guMajogeuiw==",
+      "dependencies": {
+        "@types/unist": "^2.0.0",
+        "unist-util-is": "^5.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/universalify": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
+      "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
+      "engines": {
+        "node": ">= 10.0.0"
+      }
+    },
+    "node_modules/uvu": {
+      "version": "0.5.6",
+      "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz",
+      "integrity": "sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==",
+      "dependencies": {
+        "dequal": "^2.0.0",
+        "diff": "^5.0.0",
+        "kleur": "^4.0.3",
+        "sade": "^1.7.3"
+      },
+      "bin": {
+        "uvu": "bin.js"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/vfile": {
+      "version": "5.3.6",
+      "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.6.tgz",
+      "integrity": "sha512-ADBsmerdGBs2WYckrLBEmuETSPyTD4TuLxTrw0DvjirxW1ra4ZwkbzG8ndsv3Q57smvHxo677MHaQrY9yxH8cA==",
+      "dependencies": {
+        "@types/unist": "^2.0.0",
+        "is-buffer": "^2.0.0",
+        "unist-util-stringify-position": "^3.0.0",
+        "vfile-message": "^3.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/vfile-message": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.3.tgz",
+      "integrity": "sha512-0yaU+rj2gKAyEk12ffdSbBfjnnj+b1zqTBv3OQCTn8yEB02bsPizwdBPrLJjHnK+cU9EMMcUnNv938XcZIkmdA==",
+      "dependencies": {
+        "@types/unist": "^2.0.0",
+        "unist-util-stringify-position": "^3.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/wrap-ansi": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+      "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+      "dependencies": {
+        "ansi-styles": "^4.0.0",
+        "string-width": "^4.1.0",
+        "strip-ansi": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+      }
+    },
+    "node_modules/xxhashjs": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/xxhashjs/-/xxhashjs-0.2.2.tgz",
+      "integrity": "sha512-AkTuIuVTET12tpsVIQo+ZU6f/qDmKuRUcjaqR+OIvm+aCBsZ95i7UVY5WJ9TMsSaZ0DA2WxoZ4acu0sPH+OKAw==",
+      "dependencies": {
+        "cuint": "^0.2.2"
+      }
+    },
+    "node_modules/y18n": {
+      "version": "5.0.8",
+      "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+      "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/yargs": {
+      "version": "17.6.2",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz",
+      "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==",
+      "dependencies": {
+        "cliui": "^8.0.1",
+        "escalade": "^3.1.1",
+        "get-caller-file": "^2.0.5",
+        "require-directory": "^2.1.1",
+        "string-width": "^4.2.3",
+        "y18n": "^5.0.5",
+        "yargs-parser": "^21.1.1"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/yargs-parser": {
+      "version": "21.1.1",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+      "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/zwitch": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz",
+      "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    }
+  },
+  "dependencies": {
+    "@adobe/helix-log": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/@adobe/helix-log/-/helix-log-6.0.0.tgz",
+      "integrity": "sha512-+9gpf49sFDmZLV3gtjY+RmEUistqYJdVWpiqlRYpxE59x5bHFzYf93dZ7fljSTBtZdVq8lm97HxrTUloh5HvRg==",
+      "requires": {
+        "big.js": "^6.1.1",
+        "colorette": "^2.0.2",
+        "ferrum": "^1.9.3",
+        "phin": "^3.6.0",
+        "polka": "^0.5.2"
+      }
+    },
+    "@adobe/jsonschema2md": {
+      "version": "7.1.5",
+      "resolved": "https://registry.npmjs.org/@adobe/jsonschema2md/-/jsonschema2md-7.1.5.tgz",
+      "integrity": "sha512-uybF3Ryn0xz5lzGz6sb6Th5nkX9H60zOnKVYCUXunUtWENGb7Ut+8CYPzPA9sjY8+gLK8pQq3rbmsKprcjkN0A==",
+      "requires": {
+        "@adobe/helix-log": "6.0.0",
+        "@types/json-schema": "^7.0.8",
+        "@types/mdast": "^3.0.4",
+        "es2015-i18n-tag": "1.6.1",
+        "ferrum": "1.9.4",
+        "fs-extra": "11.1.0",
+        "github-slugger": "2.0.0",
+        "js-yaml": "4.1.0",
+        "json-schema": "^0.4.0",
+        "mdast-builder": "1.1.1",
+        "mdast-util-to-string": "3.1.0",
+        "readdirp": "3.6.0",
+        "remark-gfm": "^3.0.0",
+        "remark-parse": "10.0.1",
+        "remark-stringify": "10.0.2",
+        "unified": "10.1.2",
+        "unist-util-inspect": "7.0.1",
+        "yargs": "17.6.2"
+      }
+    },
+    "@arr/every": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@arr/every/-/every-1.0.1.tgz",
+      "integrity": "sha512-UQFQ6SgyJ6LX42W8rHCs8KVc0JS0tzVL9ct4XYedJukskYVWTo49tNiMEK9C2HTyarbNiT/RVIRSY82vH+6sTg=="
+    },
+    "@polka/url": {
+      "version": "0.5.0",
+      "resolved": "https://registry.npmjs.org/@polka/url/-/url-0.5.0.tgz",
+      "integrity": "sha512-oZLYFEAzUKyi3SKnXvj32ZCEGH6RDnao7COuCVhDydMS9NrCSVXhM79VaKyP5+Zc33m0QXEd2DN3UkU7OsHcfw=="
+    },
+    "@types/debug": {
+      "version": "4.1.7",
+      "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz",
+      "integrity": "sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==",
+      "requires": {
+        "@types/ms": "*"
+      }
+    },
+    "@types/json-schema": {
+      "version": "7.0.11",
+      "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
+      "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ=="
+    },
+    "@types/mdast": {
+      "version": "3.0.10",
+      "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.10.tgz",
+      "integrity": "sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==",
+      "requires": {
+        "@types/unist": "*"
+      }
+    },
+    "@types/ms": {
+      "version": "0.7.31",
+      "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz",
+      "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA=="
+    },
+    "@types/unist": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz",
+      "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ=="
+    },
+    "ansi-regex": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
+    },
+    "ansi-styles": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+      "requires": {
+        "color-convert": "^2.0.1"
+      }
+    },
+    "argparse": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+      "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
+    },
+    "bail": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz",
+      "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw=="
+    },
+    "big.js": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/big.js/-/big.js-6.2.1.tgz",
+      "integrity": "sha512-bCtHMwL9LeDIozFn+oNhhFoq+yQ3BNdnsLSASUxLciOb1vgvpHsIO1dsENiGMgbb4SkP5TrzWzRiLddn8ahVOQ=="
+    },
+    "ccount": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz",
+      "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="
+    },
+    "centra": {
+      "version": "2.6.0",
+      "resolved": "https://registry.npmjs.org/centra/-/centra-2.6.0.tgz",
+      "integrity": "sha512-dgh+YleemrT8u85QL11Z6tYhegAs3MMxsaWAq/oXeAmYJ7VxL3SI9TZtnfaEvNDMAPolj25FXIb3S+HCI4wQaQ=="
+    },
+    "character-entities": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz",
+      "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ=="
+    },
+    "cliui": {
+      "version": "8.0.1",
+      "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+      "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
+      "requires": {
+        "string-width": "^4.2.0",
+        "strip-ansi": "^6.0.1",
+        "wrap-ansi": "^7.0.0"
+      }
+    },
+    "color-convert": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+      "requires": {
+        "color-name": "~1.1.4"
+      }
+    },
+    "color-name": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+    },
+    "colorette": {
+      "version": "2.0.19",
+      "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz",
+      "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ=="
+    },
+    "cuint": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/cuint/-/cuint-0.2.2.tgz",
+      "integrity": "sha512-d4ZVpCW31eWwCMe1YT3ur7mUDnTXbgwyzaL320DrcRT45rfjYxkt5QWLrmOJ+/UEAI2+fQgKe/fCjR8l4TpRgw=="
+    },
+    "debug": {
+      "version": "4.3.4",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+      "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+      "requires": {
+        "ms": "2.1.2"
+      }
+    },
+    "decode-named-character-reference": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz",
+      "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==",
+      "requires": {
+        "character-entities": "^2.0.0"
+      }
+    },
+    "dequal": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
+      "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="
+    },
+    "diff": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz",
+      "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw=="
+    },
+    "emoji-regex": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
+    },
+    "es2015-i18n-tag": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/es2015-i18n-tag/-/es2015-i18n-tag-1.6.1.tgz",
+      "integrity": "sha512-MYoh9p+JTkgnzBh0MEBON6xUyzdmwT6wzsmmFJvZujGSXiI2kM+3XvFl6+AcIO2eeL6VWgtX9szSiDTMwDxyYA=="
+    },
+    "escalade": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+      "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw=="
+    },
+    "escape-string-regexp": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz",
+      "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="
+    },
+    "extend": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+      "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
+    },
+    "fastestsmallesttextencoderdecoder": {
+      "version": "1.0.22",
+      "resolved": "https://registry.npmjs.org/fastestsmallesttextencoderdecoder/-/fastestsmallesttextencoderdecoder-1.0.22.tgz",
+      "integrity": "sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw=="
+    },
+    "ferrum": {
+      "version": "1.9.4",
+      "resolved": "https://registry.npmjs.org/ferrum/-/ferrum-1.9.4.tgz",
+      "integrity": "sha512-ooNerLoIht/dK4CQJux93z/hnt9JysrXniJCI3r6YRgmHeXC57EJ8XaTCT1Gm8LfhIAeWxyJA0O7d/W3pqDYRg==",
+      "requires": {
+        "fastestsmallesttextencoderdecoder": "1.0.22",
+        "lodash.isplainobject": "4.0.6",
+        "xxhashjs": "0.2.2"
+      }
+    },
+    "fs-extra": {
+      "version": "11.1.0",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.0.tgz",
+      "integrity": "sha512-0rcTq621PD5jM/e0a3EJoGC/1TC5ZBCERW82LQuwfGnCa1V8w7dpYH1yNu+SLb6E5dkeCBzKEyLGlFrnr+dUyw==",
+      "requires": {
+        "graceful-fs": "^4.2.0",
+        "jsonfile": "^6.0.1",
+        "universalify": "^2.0.0"
+      }
+    },
+    "get-caller-file": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+      "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="
+    },
+    "github-slugger": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz",
+      "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw=="
+    },
+    "graceful-fs": {
+      "version": "4.2.10",
+      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
+      "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA=="
+    },
+    "is-buffer": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz",
+      "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ=="
+    },
+    "is-fullwidth-code-point": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
+    },
+    "is-plain-obj": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz",
+      "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg=="
+    },
+    "js-yaml": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+      "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+      "requires": {
+        "argparse": "^2.0.1"
+      }
+    },
+    "json-schema": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
+      "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="
+    },
+    "jsonfile": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
+      "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+      "requires": {
+        "graceful-fs": "^4.1.6",
+        "universalify": "^2.0.0"
+      }
+    },
+    "kleur": {
+      "version": "4.1.5",
+      "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
+      "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ=="
+    },
+    "lodash.isplainobject": {
+      "version": "4.0.6",
+      "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
+      "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="
+    },
+    "longest-streak": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz",
+      "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g=="
+    },
+    "markdown-table": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz",
+      "integrity": "sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw=="
+    },
+    "matchit": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/matchit/-/matchit-1.1.0.tgz",
+      "integrity": "sha512-+nGYoOlfHmxe5BW5tE0EMJppXEwdSf8uBA1GTZC7Q77kbT35+VKLYJMzVNWCHSsga1ps1tPYFtFyvxvKzWVmMA==",
+      "requires": {
+        "@arr/every": "^1.0.0"
+      }
+    },
+    "mdast-builder": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/mdast-builder/-/mdast-builder-1.1.1.tgz",
+      "integrity": "sha512-a3KBk/LmYD6wKsWi8WJrGU/rXR4yuF4Men0JO0z6dSZCm5FrXXWTRDjqK0vGSqa+1M6p9edeuypZAZAzSehTUw==",
+      "requires": {
+        "@types/unist": "^2.0.3"
+      }
+    },
+    "mdast-util-find-and-replace": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-2.2.1.tgz",
+      "integrity": "sha512-SobxkQXFAdd4b5WmEakmkVoh18icjQRxGy5OWTCzgsLRm1Fu/KCtwD1HIQSsmq5ZRjVH0Ehwg6/Fn3xIUk+nKw==",
+      "requires": {
+        "escape-string-regexp": "^5.0.0",
+        "unist-util-is": "^5.0.0",
+        "unist-util-visit-parents": "^5.0.0"
+      }
+    },
+    "mdast-util-from-markdown": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.2.0.tgz",
+      "integrity": "sha512-iZJyyvKD1+K7QX1b5jXdE7Sc5dtoTry1vzV28UZZe8Z1xVnB/czKntJ7ZAkG0tANqRnBF6p3p7GpU1y19DTf2Q==",
+      "requires": {
+        "@types/mdast": "^3.0.0",
+        "@types/unist": "^2.0.0",
+        "decode-named-character-reference": "^1.0.0",
+        "mdast-util-to-string": "^3.1.0",
+        "micromark": "^3.0.0",
+        "micromark-util-decode-numeric-character-reference": "^1.0.0",
+        "micromark-util-decode-string": "^1.0.0",
+        "micromark-util-normalize-identifier": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0",
+        "unist-util-stringify-position": "^3.0.0",
+        "uvu": "^0.5.0"
+      }
+    },
+    "mdast-util-gfm": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-2.0.1.tgz",
+      "integrity": "sha512-42yHBbfWIFisaAfV1eixlabbsa6q7vHeSPY+cg+BBjX51M8xhgMacqH9g6TftB/9+YkcI0ooV4ncfrJslzm/RQ==",
+      "requires": {
+        "mdast-util-from-markdown": "^1.0.0",
+        "mdast-util-gfm-autolink-literal": "^1.0.0",
+        "mdast-util-gfm-footnote": "^1.0.0",
+        "mdast-util-gfm-strikethrough": "^1.0.0",
+        "mdast-util-gfm-table": "^1.0.0",
+        "mdast-util-gfm-task-list-item": "^1.0.0",
+        "mdast-util-to-markdown": "^1.0.0"
+      }
+    },
+    "mdast-util-gfm-autolink-literal": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-1.0.2.tgz",
+      "integrity": "sha512-FzopkOd4xTTBeGXhXSBU0OCDDh5lUj2rd+HQqG92Ld+jL4lpUfgX2AT2OHAVP9aEeDKp7G92fuooSZcYJA3cRg==",
+      "requires": {
+        "@types/mdast": "^3.0.0",
+        "ccount": "^2.0.0",
+        "mdast-util-find-and-replace": "^2.0.0",
+        "micromark-util-character": "^1.0.0"
+      }
+    },
+    "mdast-util-gfm-footnote": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-1.0.1.tgz",
+      "integrity": "sha512-p+PrYlkw9DeCRkTVw1duWqPRHX6Ywh2BNKJQcZbCwAuP/59B0Lk9kakuAd7KbQprVO4GzdW8eS5++A9PUSqIyw==",
+      "requires": {
+        "@types/mdast": "^3.0.0",
+        "mdast-util-to-markdown": "^1.3.0",
+        "micromark-util-normalize-identifier": "^1.0.0"
+      }
+    },
+    "mdast-util-gfm-strikethrough": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-1.0.2.tgz",
+      "integrity": "sha512-T/4DVHXcujH6jx1yqpcAYYwd+z5lAYMw4Ls6yhTfbMMtCt0PHY4gEfhW9+lKsLBtyhUGKRIzcUA2FATVqnvPDA==",
+      "requires": {
+        "@types/mdast": "^3.0.0",
+        "mdast-util-to-markdown": "^1.3.0"
+      }
+    },
+    "mdast-util-gfm-table": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-1.0.6.tgz",
+      "integrity": "sha512-uHR+fqFq3IvB3Rd4+kzXW8dmpxUhvgCQZep6KdjsLK4O6meK5dYZEayLtIxNus1XO3gfjfcIFe8a7L0HZRGgag==",
+      "requires": {
+        "@types/mdast": "^3.0.0",
+        "markdown-table": "^3.0.0",
+        "mdast-util-from-markdown": "^1.0.0",
+        "mdast-util-to-markdown": "^1.3.0"
+      }
+    },
+    "mdast-util-gfm-task-list-item": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-1.0.1.tgz",
+      "integrity": "sha512-KZ4KLmPdABXOsfnM6JHUIjxEvcx2ulk656Z/4Balw071/5qgnhz+H1uGtf2zIGnrnvDC8xR4Fj9uKbjAFGNIeA==",
+      "requires": {
+        "@types/mdast": "^3.0.0",
+        "mdast-util-to-markdown": "^1.3.0"
+      }
+    },
+    "mdast-util-to-markdown": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.4.0.tgz",
+      "integrity": "sha512-IjXARf/O8VGx/pc5SZ7syfydq1DYL9vd92orsG5U0b4GNCmAvXzu+n7sbzfIKrXwB0AVrYk3NV2kXl0AIi9LCA==",
+      "requires": {
+        "@types/mdast": "^3.0.0",
+        "@types/unist": "^2.0.0",
+        "longest-streak": "^3.0.0",
+        "mdast-util-to-string": "^3.0.0",
+        "micromark-util-decode-string": "^1.0.0",
+        "unist-util-visit": "^4.0.0",
+        "zwitch": "^2.0.0"
+      }
+    },
+    "mdast-util-to-string": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.1.0.tgz",
+      "integrity": "sha512-n4Vypz/DZgwo0iMHLQL49dJzlp7YtAJP+N07MZHpjPf/5XJuHUWstviF4Mn2jEiR/GNmtnRRqnwsXExk3igfFA=="
+    },
+    "micromark": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.1.0.tgz",
+      "integrity": "sha512-6Mj0yHLdUZjHnOPgr5xfWIMqMWS12zDN6iws9SLuSz76W8jTtAv24MN4/CL7gJrl5vtxGInkkqDv/JIoRsQOvA==",
+      "requires": {
+        "@types/debug": "^4.0.0",
+        "debug": "^4.0.0",
+        "decode-named-character-reference": "^1.0.0",
+        "micromark-core-commonmark": "^1.0.1",
+        "micromark-factory-space": "^1.0.0",
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-chunked": "^1.0.0",
+        "micromark-util-combine-extensions": "^1.0.0",
+        "micromark-util-decode-numeric-character-reference": "^1.0.0",
+        "micromark-util-encode": "^1.0.0",
+        "micromark-util-normalize-identifier": "^1.0.0",
+        "micromark-util-resolve-all": "^1.0.0",
+        "micromark-util-sanitize-uri": "^1.0.0",
+        "micromark-util-subtokenize": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.1",
+        "uvu": "^0.5.0"
+      }
+    },
+    "micromark-core-commonmark": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.0.6.tgz",
+      "integrity": "sha512-K+PkJTxqjFfSNkfAhp4GB+cZPfQd6dxtTXnf+RjZOV7T4EEXnvgzOcnp+eSTmpGk9d1S9sL6/lqrgSNn/s0HZA==",
+      "requires": {
+        "decode-named-character-reference": "^1.0.0",
+        "micromark-factory-destination": "^1.0.0",
+        "micromark-factory-label": "^1.0.0",
+        "micromark-factory-space": "^1.0.0",
+        "micromark-factory-title": "^1.0.0",
+        "micromark-factory-whitespace": "^1.0.0",
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-chunked": "^1.0.0",
+        "micromark-util-classify-character": "^1.0.0",
+        "micromark-util-html-tag-name": "^1.0.0",
+        "micromark-util-normalize-identifier": "^1.0.0",
+        "micromark-util-resolve-all": "^1.0.0",
+        "micromark-util-subtokenize": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.1",
+        "uvu": "^0.5.0"
+      }
+    },
+    "micromark-extension-gfm": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-2.0.1.tgz",
+      "integrity": "sha512-p2sGjajLa0iYiGQdT0oelahRYtMWvLjy8J9LOCxzIQsllMCGLbsLW+Nc+N4vi02jcRJvedVJ68cjelKIO6bpDA==",
+      "requires": {
+        "micromark-extension-gfm-autolink-literal": "^1.0.0",
+        "micromark-extension-gfm-footnote": "^1.0.0",
+        "micromark-extension-gfm-strikethrough": "^1.0.0",
+        "micromark-extension-gfm-table": "^1.0.0",
+        "micromark-extension-gfm-tagfilter": "^1.0.0",
+        "micromark-extension-gfm-task-list-item": "^1.0.0",
+        "micromark-util-combine-extensions": "^1.0.0",
+        "micromark-util-types": "^1.0.0"
+      }
+    },
+    "micromark-extension-gfm-autolink-literal": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-1.0.3.tgz",
+      "integrity": "sha512-i3dmvU0htawfWED8aHMMAzAVp/F0Z+0bPh3YrbTPPL1v4YAlCZpy5rBO5p0LPYiZo0zFVkoYh7vDU7yQSiCMjg==",
+      "requires": {
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-sanitize-uri": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0",
+        "uvu": "^0.5.0"
+      }
+    },
+    "micromark-extension-gfm-footnote": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-1.0.4.tgz",
+      "integrity": "sha512-E/fmPmDqLiMUP8mLJ8NbJWJ4bTw6tS+FEQS8CcuDtZpILuOb2kjLqPEeAePF1djXROHXChM/wPJw0iS4kHCcIg==",
+      "requires": {
+        "micromark-core-commonmark": "^1.0.0",
+        "micromark-factory-space": "^1.0.0",
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-normalize-identifier": "^1.0.0",
+        "micromark-util-sanitize-uri": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0",
+        "uvu": "^0.5.0"
+      }
+    },
+    "micromark-extension-gfm-strikethrough": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-1.0.4.tgz",
+      "integrity": "sha512-/vjHU/lalmjZCT5xt7CcHVJGq8sYRm80z24qAKXzaHzem/xsDYb2yLL+NNVbYvmpLx3O7SYPuGL5pzusL9CLIQ==",
+      "requires": {
+        "micromark-util-chunked": "^1.0.0",
+        "micromark-util-classify-character": "^1.0.0",
+        "micromark-util-resolve-all": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0",
+        "uvu": "^0.5.0"
+      }
+    },
+    "micromark-extension-gfm-table": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-1.0.5.tgz",
+      "integrity": "sha512-xAZ8J1X9W9K3JTJTUL7G6wSKhp2ZYHrFk5qJgY/4B33scJzE2kpfRL6oiw/veJTbt7jiM/1rngLlOKPWr1G+vg==",
+      "requires": {
+        "micromark-factory-space": "^1.0.0",
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0",
+        "uvu": "^0.5.0"
+      }
+    },
+    "micromark-extension-gfm-tagfilter": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-1.0.1.tgz",
+      "integrity": "sha512-Ty6psLAcAjboRa/UKUbbUcwjVAv5plxmpUTy2XC/3nJFL37eHej8jrHrRzkqcpipJliuBH30DTs7+3wqNcQUVA==",
+      "requires": {
+        "micromark-util-types": "^1.0.0"
+      }
+    },
+    "micromark-extension-gfm-task-list-item": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-1.0.3.tgz",
+      "integrity": "sha512-PpysK2S1Q/5VXi72IIapbi/jliaiOFzv7THH4amwXeYXLq3l1uo8/2Be0Ac1rEwK20MQEsGH2ltAZLNY2KI/0Q==",
+      "requires": {
+        "micromark-factory-space": "^1.0.0",
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0",
+        "uvu": "^0.5.0"
+      }
+    },
+    "micromark-factory-destination": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.0.0.tgz",
+      "integrity": "sha512-eUBA7Rs1/xtTVun9TmV3gjfPz2wEwgK5R5xcbIM5ZYAtvGF6JkyaDsj0agx8urXnO31tEO6Ug83iVH3tdedLnw==",
+      "requires": {
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0"
+      }
+    },
+    "micromark-factory-label": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.0.2.tgz",
+      "integrity": "sha512-CTIwxlOnU7dEshXDQ+dsr2n+yxpP0+fn271pu0bwDIS8uqfFcumXpj5mLn3hSC8iw2MUr6Gx8EcKng1dD7i6hg==",
+      "requires": {
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0",
+        "uvu": "^0.5.0"
+      }
+    },
+    "micromark-factory-space": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.0.0.tgz",
+      "integrity": "sha512-qUmqs4kj9a5yBnk3JMLyjtWYN6Mzfcx8uJfi5XAveBniDevmZasdGBba5b4QsvRcAkmvGo5ACmSUmyGiKTLZew==",
+      "requires": {
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-types": "^1.0.0"
+      }
+    },
+    "micromark-factory-title": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.0.2.tgz",
+      "integrity": "sha512-zily+Nr4yFqgMGRKLpTVsNl5L4PMu485fGFDOQJQBl2NFpjGte1e86zC0da93wf97jrc4+2G2GQudFMHn3IX+A==",
+      "requires": {
+        "micromark-factory-space": "^1.0.0",
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0",
+        "uvu": "^0.5.0"
+      }
+    },
+    "micromark-factory-whitespace": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.0.0.tgz",
+      "integrity": "sha512-Qx7uEyahU1lt1RnsECBiuEbfr9INjQTGa6Err+gF3g0Tx4YEviPbqqGKNv/NrBaE7dVHdn1bVZKM/n5I/Bak7A==",
+      "requires": {
+        "micromark-factory-space": "^1.0.0",
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0"
+      }
+    },
+    "micromark-util-character": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.1.0.tgz",
+      "integrity": "sha512-agJ5B3unGNJ9rJvADMJ5ZiYjBRyDpzKAOk01Kpi1TKhlT1APx3XZk6eN7RtSz1erbWHC2L8T3xLZ81wdtGRZzg==",
+      "requires": {
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0"
+      }
+    },
+    "micromark-util-chunked": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.0.0.tgz",
+      "integrity": "sha512-5e8xTis5tEZKgesfbQMKRCyzvffRRUX+lK/y+DvsMFdabAicPkkZV6gO+FEWi9RfuKKoxxPwNL+dFF0SMImc1g==",
+      "requires": {
+        "micromark-util-symbol": "^1.0.0"
+      }
+    },
+    "micromark-util-classify-character": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.0.0.tgz",
+      "integrity": "sha512-F8oW2KKrQRb3vS5ud5HIqBVkCqQi224Nm55o5wYLzY/9PwHGXC01tr3d7+TqHHz6zrKQ72Okwtvm/xQm6OVNZA==",
+      "requires": {
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0"
+      }
+    },
+    "micromark-util-combine-extensions": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.0.0.tgz",
+      "integrity": "sha512-J8H058vFBdo/6+AsjHp2NF7AJ02SZtWaVUjsayNFeAiydTxUwViQPxN0Hf8dp4FmCQi0UUFovFsEyRSUmFH3MA==",
+      "requires": {
+        "micromark-util-chunked": "^1.0.0",
+        "micromark-util-types": "^1.0.0"
+      }
+    },
+    "micromark-util-decode-numeric-character-reference": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.0.0.tgz",
+      "integrity": "sha512-OzO9AI5VUtrTD7KSdagf4MWgHMtET17Ua1fIpXTpuhclCqD8egFWo85GxSGvxgkGS74bEahvtM0WP0HjvV0e4w==",
+      "requires": {
+        "micromark-util-symbol": "^1.0.0"
+      }
+    },
+    "micromark-util-decode-string": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.0.2.tgz",
+      "integrity": "sha512-DLT5Ho02qr6QWVNYbRZ3RYOSSWWFuH3tJexd3dgN1odEuPNxCngTCXJum7+ViRAd9BbdxCvMToPOD/IvVhzG6Q==",
+      "requires": {
+        "decode-named-character-reference": "^1.0.0",
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-decode-numeric-character-reference": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0"
+      }
+    },
+    "micromark-util-encode": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.0.1.tgz",
+      "integrity": "sha512-U2s5YdnAYexjKDel31SVMPbfi+eF8y1U4pfiRW/Y8EFVCy/vgxk/2wWTxzcqE71LHtCuCzlBDRU2a5CQ5j+mQA=="
+    },
+    "micromark-util-html-tag-name": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.1.0.tgz",
+      "integrity": "sha512-BKlClMmYROy9UiV03SwNmckkjn8QHVaWkqoAqzivabvdGcwNGMMMH/5szAnywmsTBUzDsU57/mFi0sp4BQO6dA=="
+    },
+    "micromark-util-normalize-identifier": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.0.0.tgz",
+      "integrity": "sha512-yg+zrL14bBTFrQ7n35CmByWUTFsgst5JhA4gJYoty4Dqzj4Z4Fr/DHekSS5aLfH9bdlfnSvKAWsAgJhIbogyBg==",
+      "requires": {
+        "micromark-util-symbol": "^1.0.0"
+      }
+    },
+    "micromark-util-resolve-all": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.0.0.tgz",
+      "integrity": "sha512-CB/AGk98u50k42kvgaMM94wzBqozSzDDaonKU7P7jwQIuH2RU0TeBqGYJz2WY1UdihhjweivStrJ2JdkdEmcfw==",
+      "requires": {
+        "micromark-util-types": "^1.0.0"
+      }
+    },
+    "micromark-util-sanitize-uri": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.1.0.tgz",
+      "integrity": "sha512-RoxtuSCX6sUNtxhbmsEFQfWzs8VN7cTctmBPvYivo98xb/kDEoTCtJQX5wyzIYEmk/lvNFTat4hL8oW0KndFpg==",
+      "requires": {
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-encode": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0"
+      }
+    },
+    "micromark-util-subtokenize": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.0.2.tgz",
+      "integrity": "sha512-d90uqCnXp/cy4G881Ub4psE57Sf8YD0pim9QdjCRNjfas2M1u6Lbt+XZK9gnHL2XFhnozZiEdCa9CNfXSfQ6xA==",
+      "requires": {
+        "micromark-util-chunked": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0",
+        "uvu": "^0.5.0"
+      }
+    },
+    "micromark-util-symbol": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.0.1.tgz",
+      "integrity": "sha512-oKDEMK2u5qqAptasDAwWDXq0tG9AssVwAx3E9bBF3t/shRIGsWIRG+cGafs2p/SnDSOecnt6hZPCE2o6lHfFmQ=="
+    },
+    "micromark-util-types": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.0.2.tgz",
+      "integrity": "sha512-DCfg/T8fcrhrRKTPjRrw/5LLvdGV7BHySf/1LOZx7TzWZdYRjogNtyNq885z3nNallwr3QUKARjqvHqX1/7t+w=="
+    },
+    "mri": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
+      "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA=="
+    },
+    "ms": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+    },
+    "phin": {
+      "version": "3.7.0",
+      "resolved": "https://registry.npmjs.org/phin/-/phin-3.7.0.tgz",
+      "integrity": "sha512-DqnVNrpYhKGBZppNKprD+UJylMeEKOZxHgPB+ZP6mGzf3uA2uox4Ep9tUm+rUc8WLIdHT3HcAE4X8fhwQA9JKg==",
+      "requires": {
+        "centra": "^2.6.0"
+      }
+    },
+    "picomatch": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="
+    },
+    "polka": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/polka/-/polka-0.5.2.tgz",
+      "integrity": "sha512-FVg3vDmCqP80tOrs+OeNlgXYmFppTXdjD5E7I4ET1NjvtNmQrb1/mJibybKkb/d4NA7YWAr1ojxuhpL3FHqdlw==",
+      "requires": {
+        "@polka/url": "^0.5.0",
+        "trouter": "^2.0.1"
+      }
+    },
+    "readdirp": {
+      "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+      "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+      "requires": {
+        "picomatch": "^2.2.1"
+      }
+    },
+    "remark-gfm": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-3.0.1.tgz",
+      "integrity": "sha512-lEFDoi2PICJyNrACFOfDD3JlLkuSbOa5Wd8EPt06HUdptv8Gn0bxYTdbU/XXQ3swAPkEaGxxPN9cbnMHvVu1Ig==",
+      "requires": {
+        "@types/mdast": "^3.0.0",
+        "mdast-util-gfm": "^2.0.0",
+        "micromark-extension-gfm": "^2.0.0",
+        "unified": "^10.0.0"
+      }
+    },
+    "remark-parse": {
+      "version": "10.0.1",
+      "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-10.0.1.tgz",
+      "integrity": "sha512-1fUyHr2jLsVOkhbvPRBJ5zTKZZyD6yZzYaWCS6BPBdQ8vEMBCH+9zNCDA6tET/zHCi/jLqjCWtlJZUPk+DbnFw==",
+      "requires": {
+        "@types/mdast": "^3.0.0",
+        "mdast-util-from-markdown": "^1.0.0",
+        "unified": "^10.0.0"
+      }
+    },
+    "remark-stringify": {
+      "version": "10.0.2",
+      "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-10.0.2.tgz",
+      "integrity": "sha512-6wV3pvbPvHkbNnWB0wdDvVFHOe1hBRAx1Q/5g/EpH4RppAII6J8Gnwe7VbHuXaoKIF6LAg6ExTel/+kNqSQ7lw==",
+      "requires": {
+        "@types/mdast": "^3.0.0",
+        "mdast-util-to-markdown": "^1.0.0",
+        "unified": "^10.0.0"
+      }
+    },
+    "require-directory": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+      "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="
+    },
+    "sade": {
+      "version": "1.8.1",
+      "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz",
+      "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==",
+      "requires": {
+        "mri": "^1.1.0"
+      }
+    },
+    "string-width": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+      "requires": {
+        "emoji-regex": "^8.0.0",
+        "is-fullwidth-code-point": "^3.0.0",
+        "strip-ansi": "^6.0.1"
+      }
+    },
+    "strip-ansi": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+      "requires": {
+        "ansi-regex": "^5.0.1"
+      }
+    },
+    "trough": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/trough/-/trough-2.1.0.tgz",
+      "integrity": "sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g=="
+    },
+    "trouter": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/trouter/-/trouter-2.0.1.tgz",
+      "integrity": "sha512-kr8SKKw94OI+xTGOkfsvwZQ8mWoikZDd2n8XZHjJVZUARZT+4/VV6cacRS6CLsH9bNm+HFIPU1Zx4CnNnb4qlQ==",
+      "requires": {
+        "matchit": "^1.0.0"
+      }
+    },
+    "unified": {
+      "version": "10.1.2",
+      "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz",
+      "integrity": "sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==",
+      "requires": {
+        "@types/unist": "^2.0.0",
+        "bail": "^2.0.0",
+        "extend": "^3.0.0",
+        "is-buffer": "^2.0.0",
+        "is-plain-obj": "^4.0.0",
+        "trough": "^2.0.0",
+        "vfile": "^5.0.0"
+      }
+    },
+    "unist-util-inspect": {
+      "version": "7.0.1",
+      "resolved": "https://registry.npmjs.org/unist-util-inspect/-/unist-util-inspect-7.0.1.tgz",
+      "integrity": "sha512-gEPeSrsYXus8012VJ00p9uZC8D0iogtLLiHlBgvS61hU22KNKduQhMKezJm83viHlLf3TYS2y9SDEFglWPDMKw==",
+      "requires": {
+        "@types/unist": "^2.0.0"
+      }
+    },
+    "unist-util-is": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz",
+      "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ=="
+    },
+    "unist-util-stringify-position": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.2.tgz",
+      "integrity": "sha512-7A6eiDCs9UtjcwZOcCpM4aPII3bAAGv13E96IkawkOAW0OhH+yRxtY0lzo8KiHpzEMfH7Q+FizUmwp8Iqy5EWg==",
+      "requires": {
+        "@types/unist": "^2.0.0"
+      }
+    },
+    "unist-util-visit": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.1.tgz",
+      "integrity": "sha512-n9KN3WV9k4h1DxYR1LoajgN93wpEi/7ZplVe02IoB4gH5ctI1AaF2670BLHQYbwj+pY83gFtyeySFiyMHJklrg==",
+      "requires": {
+        "@types/unist": "^2.0.0",
+        "unist-util-is": "^5.0.0",
+        "unist-util-visit-parents": "^5.1.1"
+      }
+    },
+    "unist-util-visit-parents": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.1.tgz",
+      "integrity": "sha512-gks4baapT/kNRaWxuGkl5BIhoanZo7sC/cUT/JToSRNL1dYoXRFl75d++NkjYk4TAu2uv2Px+l8guMajogeuiw==",
+      "requires": {
+        "@types/unist": "^2.0.0",
+        "unist-util-is": "^5.0.0"
+      }
+    },
+    "universalify": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
+      "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ=="
+    },
+    "uvu": {
+      "version": "0.5.6",
+      "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz",
+      "integrity": "sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==",
+      "requires": {
+        "dequal": "^2.0.0",
+        "diff": "^5.0.0",
+        "kleur": "^4.0.3",
+        "sade": "^1.7.3"
+      }
+    },
+    "vfile": {
+      "version": "5.3.6",
+      "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.6.tgz",
+      "integrity": "sha512-ADBsmerdGBs2WYckrLBEmuETSPyTD4TuLxTrw0DvjirxW1ra4ZwkbzG8ndsv3Q57smvHxo677MHaQrY9yxH8cA==",
+      "requires": {
+        "@types/unist": "^2.0.0",
+        "is-buffer": "^2.0.0",
+        "unist-util-stringify-position": "^3.0.0",
+        "vfile-message": "^3.0.0"
+      }
+    },
+    "vfile-message": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.3.tgz",
+      "integrity": "sha512-0yaU+rj2gKAyEk12ffdSbBfjnnj+b1zqTBv3OQCTn8yEB02bsPizwdBPrLJjHnK+cU9EMMcUnNv938XcZIkmdA==",
+      "requires": {
+        "@types/unist": "^2.0.0",
+        "unist-util-stringify-position": "^3.0.0"
+      }
+    },
+    "wrap-ansi": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+      "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+      "requires": {
+        "ansi-styles": "^4.0.0",
+        "string-width": "^4.1.0",
+        "strip-ansi": "^6.0.0"
+      }
+    },
+    "xxhashjs": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/xxhashjs/-/xxhashjs-0.2.2.tgz",
+      "integrity": "sha512-AkTuIuVTET12tpsVIQo+ZU6f/qDmKuRUcjaqR+OIvm+aCBsZ95i7UVY5WJ9TMsSaZ0DA2WxoZ4acu0sPH+OKAw==",
+      "requires": {
+        "cuint": "^0.2.2"
+      }
+    },
+    "y18n": {
+      "version": "5.0.8",
+      "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+      "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="
+    },
+    "yargs": {
+      "version": "17.6.2",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz",
+      "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==",
+      "requires": {
+        "cliui": "^8.0.1",
+        "escalade": "^3.1.1",
+        "get-caller-file": "^2.0.5",
+        "require-directory": "^2.1.1",
+        "string-width": "^4.2.3",
+        "y18n": "^5.0.5",
+        "yargs-parser": "^21.1.1"
+      }
+    },
+    "yargs-parser": {
+      "version": "21.1.1",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+      "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="
+    },
+    "zwitch": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz",
+      "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="
+    }
+  }
+}
diff --git a/doc/_static/package.json b/doc/_static/package.json
new file mode 100644 (file)
index 0000000..7e3d4e4
--- /dev/null
@@ -0,0 +1,5 @@
+{
+  "dependencies": {
+    "@adobe/jsonschema2md": "^7.1.5"
+  }
+}
diff --git a/doc/architecture.rst b/doc/architecture.rst
new file mode 100644 (file)
index 0000000..f07ed57
--- /dev/null
@@ -0,0 +1,5 @@
+
+
+*********************
+Internal architecture
+*********************
\ No newline at end of file
index c545a77632b76613e231d710dc4ed182179db095..dd0be5d6574d57de7fdbb0cb257082fc01015d19 100644 (file)
@@ -17,7 +17,8 @@ extensions = [
     'sphinx.ext.todo',
     'sphinx.ext.viewcode',
     'sphinx_tabs.tabs',
-    'breathe'
+    'breathe',
+    'myst_parser',
 ]
 
 # Breathe configuration
similarity index 100%
rename from doc/_static/.gitignore
rename to doc/config-lua.rst
diff --git a/doc/config-schema-header.md b/doc/config-schema-header.md
new file mode 100644 (file)
index 0000000..92079df
--- /dev/null
@@ -0,0 +1,4 @@
+# Config schema reference
+
+The following section is automatically generated from the [configuration JSON schema](_static/config.schema.json) and can be used as a quick reference.
+
index 2461197e7bd33d80661df46a041073d953148522..b8819aa2cbc242b88b9dacd5edb0ae0b73f5e772 100644 (file)
@@ -10,97 +10,37 @@ Configuration
    :depth: 1
    :local:
 
-Since version **6.0.0**, Knot Resolver uses new declarative configuration. Easiest way to configure the resolver is to paste your configuration into YAML file ``/etc/knot-resolver/config.yml``.
-You can start with :ref:`network interfaces <usecase-network-interfaces>`, continue with other :ref:`common use cases <usecases-chapter>` and then look in the complete :ref:`configuration <configuration-chapter>` documentation.
-
-Complete configurations files for examples can be found `here <https://gitlab.nic.cz/knot/knot-resolver/tree/master/etc/config>`_.
-The example configuration files are also installed as documentation files, typically in directory ``/usr/share/doc/knot-resolver/examples/`` (their location may be different based on your Linux distribution).
-
-.. tip::
-
-    An easy way to see the complete configuration structure is to look at the `JSON Schema <https://json-schema.org/>`_ of the configuration format with some graphical visualizer such as `this one <https://json-schema.app/>`_.
-    The raw schema is accessible from every running Knot Resolver at the HTTP API socket at path ``/schema`` or on `this link <_static/config-schema.json>`_ (valid only for the version of resolver this documentation was generated for)
-
-===================
-Management HTTP API
-===================
-
-You can use HTTP API to dynamically change configuration of already running Knot Resolver.
-By default the API is configured as UNIX domain socket ``manager.sock`` located in the resolver's rundir (typically ``/run/knot-resolver/``).
-This socket is used by ``kresctl`` utility in default.
-
-The API setting can be changed only in ``/etc/knot-resolver/config.yml`` configuration file:
-
-.. code-block:: yaml
-
-    management:
-        interface: 127.0.0.1@5000
-        # or use unix socket instead of inteface
-        # unix-socket: /my/new/socket.sock
-
-First version of configuration API endpoint is available on ``/v1/config`` HTTP endpoint.
-Configuration API supports following HTTP request methods:
-
-================================   =========================
-HTTP request methods               Operation
-================================   =========================
-**GET**    ``/v1/config[/path]``   returns current configuration with an ETag
-**PUT**    ``/v1/config[/path]``   upsert (try update, if does not exists, insert), appends to array
-**PATCH**  ``/v1/config[/path]``   update property using `JSON Patch <https://jsonpatch.com/>`_
-**DELETE** ``/v1/config[/path]``   delete an existing property or list item at given index
-================================   =========================
+Easiest way to configure the resolver is to have your configuration in the ``/etc/knot-resolver/config.yml`` YAML file. If you change the configuration while the resolver is running, you can load it into the running resolver by invoking the ``systemctl reload knot-resolver.service`` command.
 
 .. note::
 
-    Managemnet API has other useful endpoints (metrics, schema, ...), see the detailed :ref:`API documentation <manager-api>`.
+    **Reloading configuration** can fail even when your configuration is valid, because some options cannot be changed while running. You can always find an explanation of the error in the log accesed by the ``journalctl -eu knot-resolver`` command.
 
-**path:**
-    Determines specific configuration option or configuration subtree on that path.
-    Items in lists and dictionaries are reachable using indexes ``/list-name/{index}/`` and keys ``/dict-name/{key}/``.
 
-**payload:**
-    JSON or YAML encoding is used for configuration payload.
+The configuration file follows a strict schema which can be validated using ``kresctl validate /path/to/config/file`` without running the resolver.
 
-.. note::
-
-    Some configuration options cannot be configured via the API for stability and security reasons(e.g. API configuration itself).
-    In the case of an attempt to configure such an option, the operation is rejected.
-
-
-===============
-kresctl utility
-===============
-
-This command-line utility allows you to configure and control running Knot Resolver.
-For that it uses the above mentioned HTTP API.
-
-For example, folowing command changes the number of ``kresd`` workers to 4.
-
-.. code-block::
+You can continue exploring the configuration options by reading about :ref:`network interfaces <usecase-network-interfaces>`, continue with other :ref:`common use cases <usecases-chapter>` or look at the complete :ref:`configuration <configuration-chapter>` documentation.
 
-    $ kresctl config /workers 4
+Complete configurations files for examples can be found `here <https://gitlab.nic.cz/knot/knot-resolver/tree/master/etc/config>`_.
+The example configuration files are also installed as documentation files, typically in directory ``/usr/share/doc/knot-resolver/examples/`` (their location may be different based on your Linux distribution).
 
-The utility can also help with configuration **validation** and with configuration format **conversion**.
-For more information read full :ref:`kresctl documentation <manager-client>` or use ``kresctl --help`` command.
+.. tip::
 
-.. note::
+    An easy way to see the complete configuration structure is to look at the `JSON Schema <https://json-schema.org/>`_ of the configuration format with some graphical visualizer such as `this one <https://json-schema.app/>`_.
+    The raw schema is accessible from every running Knot Resolver at the HTTP API socket at path ``/schema`` or on `this link <_static/config.schema.json>`_ (valid only for the version of resolver this documentation was generated for)
 
-    With no changes in management configuration, ``kresctl`` should work out of the box.
-    In other case there is ``-s`` argument to specify path to HTTP API endpoint.
 
+==========
+Config API
+==========
 
-========================
-Legacy Lua configuration
-========================
+Configuration of the resolver can be changed at runtime through the provided :ref:`HTTP API <manager-api>`. Any changes made during runtime are not persistent unless you modify the configuration file yourself. Also, changing the configuration through the API does not introduce any downtime to the provided service.
 
-Legacy way to configure Knot Resolver daemon is to paste your configuration into configuration file ``/etc/knot-resolver/kresd.conf``.
-When using this configuration approach, the daemon must be started using legacy systemd service ``kresd@``.
+The API can be used from the command-line with the :ref:`kresctl utility <manager-kresctl>`.
 
-.. note::
 
-    When copy&pasting examples from this manual please pay close
-    attention to brackets and also line ordering - order of lines matters.
+=================
+Lua configuration
+=================
 
-    The configuration language is in fact Lua script, so you can use full power
-    of this programming language. See article
-    `Learn Lua in 15 minutes <http://tylerneylon.com/a/learn-lua/>`_ for a syntax overview.
+When reading the documentation, whenever you see a configuration snippet, you might see a Lua version of the configuration as well. Lua was used earlier as the main configuration language. Starting with Knot Resolver version 6.0.0 it was replaced by the YAML configuration we wrote about in all sections above. Lua will remain supported and in use internally, however unless want to do something really advanced, you should ignore it and use the YAML configuration. You can learn more about the Lua configuration in :ref:`this section <config-lua>`.
\ No newline at end of file
index d62f017fbdfe0522bb612d06e39ade897901a583..85a311c9e3590c46d3b3220f20e99e8008a9ee61 100644 (file)
@@ -19,15 +19,6 @@ See logs and status of running instance with ``systemctl status knot-resolver.se
     ``knot-resolver.service`` is not enabled by default, thus Knot Resolver won't start automatically after reboot.
     To start and enable service in one command use ``systemctl enable --now knot-resolver.service``
 
-=====================
-Legacy daemon startup
-=====================
-
-Legacy way to run single instance of Knot Resolver daemon is to use ``kresd@`` systemd integration:
-
-.. code-block:: bash
-
-   $ sudo systemctl start kresd@1.service
 
 ===============
 First DNS query
index c39dc0bded36718a08834691cf66e4dcc4fc9007..4c5f4944b071da1d309accfb8e9c38aef3c73e80 100644 (file)
@@ -18,6 +18,7 @@ and it provides a state-machine like API for extensions.
    gettingstarted-install
    gettingstarted-startup
    gettingstarted-config
+   upgrading-to-6
 
 
 .. toctree::
@@ -25,10 +26,10 @@ and it provides a state-machine like API for extensions.
    :name: usecases-chapter
    :maxdepth: 1
 
-   usecase-network-interfaces
+   usecase-personal-resolver
    usecase-internal-resolver
    usecase-isp-resolver
-   usecase-personal-resolver
+   usecase-network-interfaces
 
 
 .. toctree::
@@ -46,6 +47,7 @@ and it provides a state-machine like API for extensions.
    :maxdepth: 3
 
    config-overview
+   config-schema
    config-network
    config-performance
    config-policy
@@ -69,6 +71,7 @@ and it provides a state-machine like API for extensions.
    :name: developers-chapter
    :maxdepth: 2
 
+   architecture
    build
    lib
    modules_api
diff --git a/doc/legacy.rst b/doc/legacy.rst
new file mode 100644 (file)
index 0000000..cf2c6aa
--- /dev/null
@@ -0,0 +1,26 @@
+=====================
+Legacy daemon startup
+=====================
+
+Legacy way to run single instance of Knot Resolver daemon is to use ``kresd@`` systemd integration:
+
+.. code-block:: bash
+
+   $ sudo systemctl start kresd@1.service
+
+
+========================
+Legacy Lua configuration
+========================
+
+Legacy way to configure Knot Resolver daemon is to paste your configuration into configuration file ``/etc/knot-resolver/kresd.conf``.
+When using this configuration approach, the daemon must be started using legacy systemd service ``kresd@``.
+
+.. note::
+
+    When copy&pasting examples from this manual please pay close
+    attention to brackets and also line ordering - order of lines matters.
+
+    The configuration language is in fact Lua script, so you can use full power
+    of this programming language. See article
+    `Learn Lua in 15 minutes <http://tylerneylon.com/a/learn-lua/>`_ for a syntax overview.
\ No newline at end of file
index ff4a90ddd2730a97d2f44d616827a88f2707a25c..29f5fb8f1d43cd83731e2c1c0c7ba18480053811 100644 (file)
@@ -6,6 +6,54 @@
 HTTP API
 ********
 
+===================
+Management HTTP API
+===================
+
+You can use HTTP API to dynamically change configuration of already running Knot Resolver.
+By default the API is configured as UNIX domain socket ``manager.sock`` located in the resolver's rundir (typically ``/run/knot-resolver/``).
+This socket is used by ``kresctl`` utility in default.
+
+The API setting can be changed only in ``/etc/knot-resolver/config.yml`` configuration file:
+
+.. code-block:: yaml
+
+    management:
+        interface: 127.0.0.1@5000
+        # or use unix socket instead of inteface
+        # unix-socket: /my/new/socket.sock
+
+First version of configuration API endpoint is available on ``/v1/config`` HTTP endpoint.
+Configuration API supports following HTTP request methods:
+
+================================   =========================
+HTTP request methods               Operation
+================================   =========================
+**GET**    ``/v1/config[/path]``   returns current configuration with an ETag
+**PUT**    ``/v1/config[/path]``   upsert (try update, if does not exists, insert), appends to array
+**PATCH**  ``/v1/config[/path]``   update property using `JSON Patch <https://jsonpatch.com/>`_
+**DELETE** ``/v1/config[/path]``   delete an existing property or list item at given index
+================================   =========================
+
+.. note::
+
+    Managemnet API has other useful endpoints (metrics, schema, ...), see the detailed :ref:`API documentation <manager-api>`.
+
+**path:**
+    Determines specific configuration option or configuration subtree on that path.
+    Items in lists and dictionaries are reachable using indexes ``/list-name/{index}/`` and keys ``/dict-name/{key}/``.
+
+**payload:**
+    JSON or YAML encoding is used for configuration payload.
+
+.. note::
+
+    Some configuration options cannot be configured via the API for stability and security reasons(e.g. API configuration itself).
+    In the case of an attempt to configure such an option, the operation is rejected.
+
+
+
+
 ===================================
 Dynamically changing configuration
 ===================================
diff --git a/doc/manager-kresctl.rst b/doc/manager-kresctl.rst
new file mode 100644 (file)
index 0000000..a5c2e14
--- /dev/null
@@ -0,0 +1,20 @@
+===============
+kresctl utility
+===============
+
+This command-line utility allows you to configure and control running Knot Resolver.
+For that it uses the above mentioned HTTP API.
+
+For example, folowing command changes the number of ``kresd`` workers to 4.
+
+.. code-block::
+
+    $ kresctl config /workers 4
+
+The utility can also help with configuration **validation** and with configuration format **conversion**.
+For more information read full :ref:`kresctl documentation <manager-client>` or use ``kresctl --help`` command.
+
+.. note::
+
+    With no changes in management configuration, ``kresctl`` should work out of the box.
+    In other case there is ``-s`` argument to specify path to HTTP API endpoint.
\ No newline at end of file
index 7595ef805c021209637c4afc00deb389e4daa7c4..1883ab80919af442c27069b2c32b65e87f1ef5cf 100644 (file)
@@ -38,30 +38,35 @@ if get_option('doc') == 'enabled'
   # python dependencies: breathe, sphinx_rtd_theme
   python_breathe = run_command('python3', '-c', 'import breathe', check: false)
   if python_breathe.returncode() != 0
-    # some distros might use python2 sphinx
     python_breathe = run_command('python2', '-c', 'import breathe', check: false)
     if python_breathe.returncode() != 0
       error('missing doc dependency: python breathe')
-    else
-      python_sphinx_rtd_theme = run_command('python2', '-c', 'import sphinx_rtd_theme', check: false)
-      if python_sphinx_rtd_theme.returncode() != 0
-             error('missing doc dependency: python sphinx_rtd_theme')
-      endif
-      python_sphinx_tabs = run_command('python2', '-c', 'import sphinx_tabs', check: false)
-      if python_sphinx_tabs.returncode() != 0
-        error('missing doc dependency: python python-sphinx-tabs')
-      endif
     endif
+    python = 'python2'
   else
-    python_sphinx_rtd_theme = run_command('python3', '-c', 'import sphinx_rtd_theme', check: false)
-    if python_sphinx_rtd_theme.returncode() != 0
-      error('missing doc dependency: sphinx_rtd_theme')
-    endif
-    python_sphinx_tabs = run_command('python3', '-c', 'import sphinx_tabs', check: false)
-    if python_sphinx_tabs.returncode() != 0
-      error('missing doc dependency: python sphinx-tabs')
-    endif
+    python = 'python3'
+  endif
+
+  python_sphinx_rtd_theme = run_command(python, '-c', 'import sphinx_rtd_theme', check: false)
+  if python_sphinx_rtd_theme.returncode() != 0
+    error('missing doc dependency: python sphinx_rtd_theme')
+  endif
+
+  python_sphinx_tabs = run_command(python, '-c', 'import sphinx_tabs', check: false)
+  if python_sphinx_tabs.returncode() != 0
+    error('missing doc dependency: python python-sphinx-tabs')
   endif
+
+  jsonschema2md = find_program('jsonschema2md')
+  if not jsonschema2md.found()
+    error('missing doc dependency: python jsonschema2md')
+  endif
+
+  myst_parser = run_command(python, '-c', 'import myst_parser', check: false)
+  if myst_parser.returncode() != 0
+    error('missing doc dependency: python myst_parser')
+  endif
+
   message('------------------------')
 
   # install html docs
index bc396166dc5db27420f1532c1dd3b4db9137ad2b..d04ef8a1fdd808c932d716026f77fe97eff32c70 100644 (file)
@@ -1,3 +1,5 @@
 Sphinx>=3.0.0
 sphinx-tabs
 breathe
+jsonschema2md
+myst_parser
\ No newline at end of file
diff --git a/doc/upgrading-to-6.rst b/doc/upgrading-to-6.rst
new file mode 100644 (file)
index 0000000..28af554
--- /dev/null
@@ -0,0 +1,9 @@
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _gettingstarted-startup:
+
+*****************************
+Upgrading to 6.0.0 from 5.x.x
+*****************************
+
+
index c35fb1b598a4eae366371cb53fb3b5099722dd83..019273b37e5b88bdf6951285dd3da35227cf6aa1 100644 (file)
@@ -29,6 +29,11 @@ newer versions when they are released.
 .. _`supervisord`: http://supervisord.org/
 
 
+5.x to 6.0
+==========
+
+* `detailed upgrade guide <upgrading-to-6>`
+
 5.4 to 5.5
 ==========
 
index c279d3120170ca7e97c39bd8d9ccc00f39211f79..90cfc6e04f4b92dacb3f002eba5231b0b884b2b2 100644 (file)
@@ -5,3 +5,20 @@
 *****************
 Internal Resolver
 *****************
+
+When running the resolver for the local network, not much has to be changed and the configuration looks essentially the same as when running locally.
+
+.. code-block:: yaml
+
+    rundir: /var/run/knot-resolver
+    workers: auto  # run as many worker processes as there are available CPU cores
+    management:
+        unix-socket: /var/run/knot-resolver/manager.sock
+    cache:
+        storage: /var/cache/knot-resolver
+        size-max: 100MB
+    network:
+        listen:
+          - interface: 'eth0'
+            port: 53
+            kind: 'dns'
index 099f68d7e4f2aa56fa57a33a89542e1f7d7174c4..d51d039bfc109010161e4b8d5ee582b1ad3950cc 100644 (file)
@@ -5,3 +5,18 @@
 *****************
 Personal Resolver
 *****************
+
+For local usage on a single system, configuration like the following should be sufficient. Equivalent configuration is the default and should be packaged by your distribution of choice.
+
+.. code-block:: yaml
+
+    rundir: /var/run/knot-resolver
+    workers: 1
+    management:
+        unix-socket: /var/run/knot-resolver/manager.sock
+    cache:
+        storage: /var/cache/knot-resolver
+        size-max: 10MB
+    network:
+        listen:
+            - interface: 127.0.0.1@53
\ No newline at end of file
index f279afa40fa05a65429b272b2eed8fdc1b0a6201..45d29e349b5272f7c40887ca5af7c9e08dc06af5 100644 (file)
@@ -160,7 +160,15 @@ def _describe_type(typ: Type[Any]) -> Dict[Any, Any]:
 
     elif is_literal(typ):
         lit = get_generic_type_arguments(typ)
-        return {"enum": lit}
+        return {"type": "string", "enum": lit}
+
+    elif is_optional(typ):
+        desc = _describe_type(get_optional_inner_type(typ))
+        if "type" in desc:
+            desc["type"] = [desc["type"], "null"]
+            return desc
+        else:
+            return {"anyOf": [{"type": "null"}, desc]}
 
     elif is_union(typ):
         variants = get_generic_type_arguments(typ)
index 086fe4103184e8e02b0e29c59bc2329416c8b15f..648a42fb606c90d2942c1284e474b57015e2da13 100755 (executable)
@@ -7,7 +7,10 @@ cd "$(dirname ${0})/.."
 pushd manager
 ## the following python command should hopefully run without any dependencies except for standard python
 mkdir -p ../doc/_static/
-python3 -m knot_resolver_manager.cli schema > ../doc/_static/config-schema.json
+python3 -m knot_resolver_manager.cli schema > ../doc/_static/config.schema.json
+
+# generate readable version of the JSON schema. The command bellow generates a markdown document, prepends a header and lowers priority of all headings by one.
+cat ../doc/config-schema-header.md <(jsonschema2md ../doc/_static/config.schema.json /dev/stdout | sed 's/^#/##/') > ../doc/config-schema.md
 popd