diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..d4e48ab --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: PMPL-1.0-or-later +# https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners + +# All files in the repository +* @hyperpolymath diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 30c879a..c22a084 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,48 +1,19 @@ # SPDX-License-Identifier: PMPL-1.0-or-later -# Dependabot configuration for RSR-compliant repositories -# Covers common ecosystems - remove unused ones for your project +# Dependabot configuration for aerie +# Focused on actual project dependencies and noise reduction version: 2 updates: - # GitHub Actions - always include + # GitHub Actions - grouped updates to reduce PR noise - package-ecosystem: "github-actions" directory: "/" schedule: interval: "weekly" + day: "monday" groups: - actions: + github-actions: patterns: - "*" - # Rust/Cargo - - package-ecosystem: "cargo" - directory: "/" - schedule: - interval: "weekly" - ignore: - - dependency-name: "*" - update-types: ["version-update:semver-patch"] - - # Elixir/Mix - - package-ecosystem: "mix" - directory: "/" - schedule: - interval: "weekly" - - # Node.js/npm - - package-ecosystem: "npm" - directory: "/" - schedule: - interval: "weekly" - - # Python/pip - - package-ecosystem: "pip" - directory: "/" - schedule: - interval: "weekly" - - # Nix flakes - - package-ecosystem: "nix" - directory: "/" - schedule: - interval: "weekly" + # No other active dependency ecosystems detected in root or primary subdirectories. + # (v.mod, build.zig, and AI.a2ml are not currently supported by Dependabot) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 61d95da..d182d4c 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -29,12 +29,12 @@ jobs: uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - name: Initialize CodeQL - uses: github/codeql-action/init@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v3.28.1 + uses: github/codeql-action/init@4dd1439054423ad07501db44cf2fd84746f8ca8e # v3.28.1 with: languages: ${{ matrix.language }} build-mode: ${{ matrix.build-mode }} - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v3.28.1 + uses: github/codeql-action/analyze@4dd1439054423ad07501db44cf2fd84746f8ca8e # v3.28.1 with: category: "/language:${{ matrix.language }}" diff --git a/.github/workflows/hypatia-scan.yml b/.github/workflows/hypatia-scan.yml index f2bf132..c789784 100644 --- a/.github/workflows/hypatia-scan.yml +++ b/.github/workflows/hypatia-scan.yml @@ -20,7 +20,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v4 with: fetch-depth: 0 # Full history for better pattern analysis diff --git a/.github/workflows/jekyll-gh-pages.yml b/.github/workflows/jekyll-gh-pages.yml deleted file mode 100644 index 9d3349d..0000000 --- a/.github/workflows/jekyll-gh-pages.yml +++ /dev/null @@ -1,52 +0,0 @@ -# SPDX-License-Identifier: PMPL-1.0-or-later -# Sample workflow for building and deploying a Jekyll site to GitHub Pages -name: Deploy Jekyll with GitHub Pages dependencies preinstalled - -on: - # Runs on pushes targeting the default branch - push: - branches: ["main"] - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages -permissions: - contents: read - pages: write - id-token: write - -# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. -# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. -concurrency: - group: "pages" - cancel-in-progress: false - -jobs: - # Build job - build: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v6.0.1 - - name: Setup Pages - uses: actions/configure-pages@v5 - - name: Build with Jekyll - uses: actions/jekyll-build-pages@v1 - with: - source: ./ - destination: ./_site - - name: Upload artifact - uses: actions/upload-pages-artifact@v4 - - # Deployment job - deploy: - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - runs-on: ubuntu-latest - needs: build - steps: - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v4 diff --git a/.github/workflows/jekyll.yml b/.github/workflows/jekyll.yml deleted file mode 100644 index 27abb52..0000000 --- a/.github/workflows/jekyll.yml +++ /dev/null @@ -1,66 +0,0 @@ -# SPDX-License-Identifier: PMPL-1.0-or-later -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. - -# Sample workflow for building and deploying a Jekyll site to GitHub Pages -name: Deploy Jekyll site to Pages - -on: - # Runs on pushes targeting the default branch - push: - branches: ["main"] - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages -permissions: - contents: read - pages: write - id-token: write - -# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. -# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. -concurrency: - group: "pages" - cancel-in-progress: false - -jobs: - # Build job - build: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v6.0.1 - - name: Setup Ruby - # https://github.com/ruby/setup-ruby/releases/tag/v1.207.0 - uses: ruby/setup-ruby@708024e6c902387ab41de36e1669e43b5ee7085e - with: - ruby-version: '3.1' # Not needed with a .ruby-version file - bundler-cache: true # runs 'bundle install' and caches installed gems automatically - cache-version: 0 # Increment this number if you need to re-download cached gems - - name: Setup Pages - id: pages - uses: actions/configure-pages@v5 - - name: Build with Jekyll - # Outputs to the './_site' directory by default - run: bundle exec jekyll build --baseurl "${{ steps.pages.outputs.base_path }}" - env: - JEKYLL_ENV: production - - name: Upload artifact - # Automatically uploads an artifact from the './_site' directory by default - uses: actions/upload-pages-artifact@v4 - - # Deployment job - deploy: - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - runs-on: ubuntu-latest - needs: build - steps: - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v4 diff --git a/.github/workflows/scorecard-enforcer.yml b/.github/workflows/scorecard-enforcer.yml index e4d4c15..b2db782 100644 --- a/.github/workflows/scorecard-enforcer.yml +++ b/.github/workflows/scorecard-enforcer.yml @@ -30,7 +30,7 @@ jobs: publish_results: true - name: Upload SARIF - uses: github/codeql-action/upload-sarif@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v3 + uses: github/codeql-action/upload-sarif@4dd1439054423ad07501db44cf2fd84746f8ca8e # v3 with: sarif_file: results.sarif diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 3dbba30..1ddc9fe 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -27,6 +27,6 @@ jobs: results_format: sarif - name: Upload results - uses: github/codeql-action/upload-sarif@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v3.31.8 + uses: github/codeql-action/upload-sarif@4dd1439054423ad07501db44cf2fd84746f8ca8e # v3.31.8 with: sarif_file: results.sarif diff --git a/.github/workflows/specs-guard.yml b/.github/workflows/specs-guard.yml deleted file mode 100644 index 9cd7461..0000000 --- a/.github/workflows/specs-guard.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: Specs Guard - -on: - pull_request: - push: - paths: - - "specs/**" - - ".github/workflows/specs-guard.yml" - -jobs: - verify-specs: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Verify specs outputs - run: bash ./specs/tools/check_manifest.sh diff --git a/CII-BEST-PRACTICES.md b/CII-BEST-PRACTICES.md new file mode 100644 index 0000000..0f69376 --- /dev/null +++ b/CII-BEST-PRACTICES.md @@ -0,0 +1,29 @@ +# OpenSSF Best Practices (CII) Adherence + +This document tracks the project's adherence to the [OpenSSF Best Practices Badge](https://best-practices.coreinfrastructure.org/) criteria. + +## Summary +The aerie project is committed to following open-source security and quality best practices. + +## Change Control +- **Public Repository**: All source code is hosted on GitHub and is public. +- **Version Control**: We use Git for version control. +- **Unique Versioning**: All releases use unique version identifiers (SemVer). + +## Reporting +- **Bug Reporting Process**: Documented in `CONTRIBUTING.md`. +- **Vulnerability Reporting**: A clear `SECURITY.md` file defines the private reporting process. + +## Quality +- **Automated Builds**: We use GitHub Actions for automated builds and CI. +- **Testing**: Automated test suites are integrated into the CI pipeline. +- **New Features**: New functionality is required to have associated tests. + +## Security +- **Secure Development**: We use automated security scanners (CodeQL, Trufflehog). +- **Dependency Pinning**: GitHub Actions and critical dependencies are pinned to specific versions/SHAs. +- **No Hardcoded Secrets**: Scanned via `trufflehog` and `gitleaks`. + +## Best Practices +- **SPDX Headers**: We use SPDX license identifiers in all source files. +- **Code Review**: All changes require a pull request and code review before merging to `main`. diff --git a/SECURITY-ACKNOWLEDGMENTS.md b/SECURITY-ACKNOWLEDGMENTS.md new file mode 100644 index 0000000..66b01f0 --- /dev/null +++ b/SECURITY-ACKNOWLEDGMENTS.md @@ -0,0 +1,9 @@ +# Security Acknowledgments + +We would like to thank the following researchers for their contributions to keeping aerie safe. + +## 2026 +- Currently no entries. + +## 2025 +- Currently no entries. diff --git a/justfile b/justfile index 6275915..0b939e2 100644 --- a/justfile +++ b/justfile @@ -49,9 +49,17 @@ audit: # --- QUALITY --- +# Run all tests +tests: + @echo "=== Running Tests ===" + @if [ -d qubes-sdp ] && [ -f qubes-sdp/justfile ]; then (cd qubes-sdp && just test); fi + @if [ -d bgp-backbone-lab ] && [ -f bgp-backbone-lab/justfile ]; then (cd bgp-backbone-lab && just test); fi + @echo "Tests complete" + # Run all quality checks quality: lint tests + # Run linters lint: @echo "=== Linting ===" diff --git a/src/stale/hyperglass/docs/.gitignore b/src/stale/hyperglass/docs/.gitignore deleted file mode 100644 index 8ade9b2..0000000 --- a/src/stale/hyperglass/docs/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -.DS_Store -.env* -*.tsbuildinfo -*.tmp* -*.log -node_modules/ -fonts/ -.next -out -pages/changelog.mdx diff --git a/src/stale/hyperglass/docs/components/color.tsx b/src/stale/hyperglass/docs/components/color.tsx deleted file mode 100644 index 0234cba..0000000 --- a/src/stale/hyperglass/docs/components/color.tsx +++ /dev/null @@ -1,29 +0,0 @@ -type ColorProps = { - hex: string; - noText?: boolean; -}; - -export const Color = (props: ColorProps) => { - const { hex, noText = false } = props; - return ( - - - {noText ? "" : hex} - - - ); -}; diff --git a/src/stale/hyperglass/docs/components/docs-button.tsx b/src/stale/hyperglass/docs/components/docs-button.tsx deleted file mode 100644 index c06c177..0000000 --- a/src/stale/hyperglass/docs/components/docs-button.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import NextLink from "next/link"; -import { Button } from "nextra/components"; - -const DocsIcon = () => ( - - Docs - - -); - -export interface DocsButtonProps extends React.ComponentProps<"button"> { - href: string; - side?: "left" | "right"; -} - -export const DocsButton = (props: DocsButtonProps) => { - const { href, side = "left", ...rest } = props; - return ( - - - - ); -}; diff --git a/src/stale/hyperglass/docs/components/not-supported-icon.tsx b/src/stale/hyperglass/docs/components/not-supported-icon.tsx deleted file mode 100644 index 5176aa2..0000000 --- a/src/stale/hyperglass/docs/components/not-supported-icon.tsx +++ /dev/null @@ -1,14 +0,0 @@ -export const NotSupported = (props: React.ComponentProps<"svg">) => ( - - Not Supported - - - -); diff --git a/src/stale/hyperglass/docs/components/platforms.tsx b/src/stale/hyperglass/docs/components/platforms.tsx deleted file mode 100644 index dda7d70..0000000 --- a/src/stale/hyperglass/docs/components/platforms.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import { Code, Table, Td, Th, Tr } from "nextra/components"; -import platforms from "~/platforms.json"; -import { NotSupported } from "./not-supported-icon"; -import { Supported } from "./supported-icon"; - -export const SupportedPlatforms = () => ( - -); - -export const PlatformTable = () => ( - - - - - - - {platforms.map((spec) => ( - - - - - ))} - -
Platform KeysNatively Supported
- {spec.keys.map((key) => ( - - {key} - - ))} - {spec.native ? : }
-); diff --git a/src/stale/hyperglass/docs/components/supported-icon.tsx b/src/stale/hyperglass/docs/components/supported-icon.tsx deleted file mode 100644 index f053c38..0000000 --- a/src/stale/hyperglass/docs/components/supported-icon.tsx +++ /dev/null @@ -1,13 +0,0 @@ -export const Supported = (props: React.ComponentProps<"svg">) => ( - - Supported - - -); diff --git a/src/stale/hyperglass/docs/favicon-formats.ts b/src/stale/hyperglass/docs/favicon-formats.ts deleted file mode 100644 index 1ac6233..0000000 --- a/src/stale/hyperglass/docs/favicon-formats.ts +++ /dev/null @@ -1,80 +0,0 @@ -interface Favicon { - rel: string | null; - dimensions: [number, number]; - image_format: string; - prefix: string; -} - -export default [ - { dimensions: [48, 48], image_format: "ico", prefix: "favicon", rel: null }, - { dimensions: [16, 16], image_format: "png", prefix: "favicon", rel: "icon" }, - { dimensions: [32, 32], image_format: "png", prefix: "favicon", rel: "icon" }, - { dimensions: [64, 64], image_format: "png", prefix: "favicon", rel: "icon" }, - { dimensions: [96, 96], image_format: "png", prefix: "favicon", rel: "icon" }, - { dimensions: [180, 180], image_format: "png", prefix: "favicon", rel: "icon" }, - { - dimensions: [57, 57], - image_format: "png", - prefix: "apple-touch-icon", - rel: "apple-touch-icon", - }, - { - dimensions: [60, 60], - image_format: "png", - prefix: "apple-touch-icon", - rel: "apple-touch-icon", - }, - { - dimensions: [72, 72], - image_format: "png", - prefix: "apple-touch-icon", - rel: "apple-touch-icon", - }, - { - dimensions: [76, 76], - image_format: "png", - prefix: "apple-touch-icon", - rel: "apple-touch-icon", - }, - { - dimensions: [114, 114], - image_format: "png", - prefix: "apple-touch-icon", - rel: "apple-touch-icon", - }, - { - dimensions: [120, 120], - image_format: "png", - prefix: "apple-touch-icon", - rel: "apple-touch-icon", - }, - { - dimensions: [144, 144], - image_format: "png", - prefix: "apple-touch-icon", - rel: "apple-touch-icon", - }, - { - dimensions: [152, 152], - image_format: "png", - prefix: "apple-touch-icon", - rel: "apple-touch-icon", - }, - { - dimensions: [167, 167], - image_format: "png", - prefix: "apple-touch-icon", - rel: "apple-touch-icon", - }, - { - dimensions: [180, 180], - image_format: "png", - prefix: "apple-touch-icon", - rel: "apple-touch-icon", - }, - { dimensions: [70, 70], image_format: "png", prefix: "mstile", rel: null }, - { dimensions: [270, 270], image_format: "png", prefix: "mstile", rel: null }, - { dimensions: [310, 310], image_format: "png", prefix: "mstile", rel: null }, - { dimensions: [310, 150], image_format: "png", prefix: "mstile", rel: null }, - { dimensions: [196, 196], image_format: "png", prefix: "favicon", rel: "shortcut icon" }, -] as Favicon[]; diff --git a/src/stale/hyperglass/docs/global.d.ts b/src/stale/hyperglass/docs/global.d.ts deleted file mode 100644 index 75facdc..0000000 --- a/src/stale/hyperglass/docs/global.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -declare global { - namespace NodeJS { - interface ProcessEnv { - NODE_ENV: 'development' | 'production'; - CF_PAGES_BRANCH: string; - } - } -} diff --git a/src/stale/hyperglass/docs/global.module.css b/src/stale/hyperglass/docs/global.module.css deleted file mode 100644 index d6df9b3..0000000 --- a/src/stale/hyperglass/docs/global.module.css +++ /dev/null @@ -1,7 +0,0 @@ -.logo { - color: #d84b4b; -} - -html[class~=dark] .logo { - color: #fff; -} \ No newline at end of file diff --git a/src/stale/hyperglass/docs/next-env.d.ts b/src/stale/hyperglass/docs/next-env.d.ts deleted file mode 100644 index 4f11a03..0000000 --- a/src/stale/hyperglass/docs/next-env.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -/// -/// - -// NOTE: This file should not be edited -// see https://nextjs.org/docs/basic-features/typescript for more information. diff --git a/src/stale/hyperglass/docs/next.config.mjs b/src/stale/hyperglass/docs/next.config.mjs deleted file mode 100644 index 9223adc..0000000 --- a/src/stale/hyperglass/docs/next.config.mjs +++ /dev/null @@ -1,35 +0,0 @@ -import fs from "node:fs"; -import path from "node:path"; -import { fileURLToPath } from "node:url"; -import withNextra from "nextra"; - -function copyChangelog() { - const dir = path.dirname(fileURLToPath(import.meta.url)); - const src = path.resolve(dir, "..", "CHANGELOG.md"); - const data = fs.readFileSync(src); - const replaced = data.toString().replace("# Changelog\n\n", ""); - const dst = path.resolve(dir, "pages", "changelog.mdx"); - fs.writeFileSync(dst, replaced); -} - -copyChangelog(); - -/** - * @type {import('nextra').NextraConfig} - */ -const nextraConfig = { - theme: "nextra-theme-docs", - themeConfig: "./theme.config.tsx", -}; - -/** - * @type {import('next').NextConfig} - */ -const config = { - images: { - unoptimized: true, - }, - output: "export", -}; - -export default withNextra(nextraConfig)(config); diff --git a/src/stale/hyperglass/docs/package.json b/src/stale/hyperglass/docs/package.json deleted file mode 100644 index a63a8e9..0000000 --- a/src/stale/hyperglass/docs/package.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "hyperglass-docs", - "version": "2.0.0", - "description": "hyperglass documentation", - "private": true, - "scripts": { - "dev": "next dev", - "start": "next start", - "typecheck": "tsc --noEmit" - }, - "author": "thatmattlove ", - "license": "BSD-3-Clause-Clear", - "dependencies": { - "next": "^14.1.1", - "nextra": "3.0.0-alpha.24", - "nextra-theme-docs": "3.0.0-alpha.24", - "react": "^18.2.0", - "react-dom": "^18.2.0" - }, - "devDependencies": { - "@types/node": "^20.11.24", - "typescript": "^5.3.3" - } -} diff --git a/src/stale/hyperglass/docs/pages/_meta.tsx b/src/stale/hyperglass/docs/pages/_meta.tsx deleted file mode 100644 index 78bc398..0000000 --- a/src/stale/hyperglass/docs/pages/_meta.tsx +++ /dev/null @@ -1,42 +0,0 @@ -export default { - index: { title: "Introduction", theme: { breadcrumb: false } }, - "---": { - type: "separator", - }, - installation: "Installation", - configuration: "Configuration", - platforms: "Platforms", - plugins: "Plugins", - documentation: { - title: "Documentation", - type: "menu", - items: { - installation: { - title: "Installation", - href: "/installation", - }, - configuration: { - title: "Configuration", - href: "/configuration", - }, - plugins: { - title: "Plugins", - href: "/plugins", - }, - changelog: { - title: "Changelog", - href: "/changelog", - }, - license: { - title: "License", - href: "/license", - }, - }, - }, - demo: { - title: "Demo", - type: "page", - href: "https://demo.hyperglass.dev", - newWindow: true, - }, -}; diff --git a/src/stale/hyperglass/docs/pages/configuration/_meta.tsx b/src/stale/hyperglass/docs/pages/configuration/_meta.tsx deleted file mode 100644 index 713550e..0000000 --- a/src/stale/hyperglass/docs/pages/configuration/_meta.tsx +++ /dev/null @@ -1,7 +0,0 @@ -export default { - overview: "Overview", - config: "Config File", - devices: "Devices File", - directives: "Directives File", - examples: "Examples", -}; diff --git a/src/stale/hyperglass/docs/pages/configuration/config.mdx b/src/stale/hyperglass/docs/pages/configuration/config.mdx deleted file mode 100644 index 85262af..0000000 --- a/src/stale/hyperglass/docs/pages/configuration/config.mdx +++ /dev/null @@ -1,44 +0,0 @@ ---- -title: Configuration File -description: hyperglass config.yaml file reference ---- - -The `config.yaml` file is broken into multiple sections: - -## Top Level Parameters - -| Parameter | Type | Default Value | Description | -| :----------------- | :-------------- | :------------------------------- | :------------------------------------------------------------ | -| `org_name` | String | Beloved Hyperglass User | Your organization's name. | -| `plugins` | List of Strings | | List of hyperglass [plugins](/plugins) to load. | -| `primary_asn` | String | 65000 | Your organization's primary ASN. Used to set default UI text. | -| `request_timeout` | Number | 90 | Global timeout in seconds for all requests. | -| `site_description` | String | `org_name` Network Looking Glass | `` description, also used in the API documentation. | -| `site_title` | String | `org_name` | Browser title, also used in the default terms & conditions. | - -#### Example with Defaults - -```yaml filename="config.yaml" -org_name: Beloved Hyperglass User -plugins: [] -primary_asn: 65000 -request_timeout: 90 -site_description: Beloved Hyperglass User Network Looking Glass -site_title: Beloved Hyperglass User -``` - -## Other Configuration Sections - -| Parameter | Docs | Description | -| :----------- | :--------------------------------------------------------------------- | :--------------------------------------------------------------- | -| `cache` | [Caching Docs](/configuration/config/caching.mdx) | Customize how hyperglass caches responses. | -| `logging` | [Logging Docs](/configuration/config/logging.mdx) | Customize file logging, syslog, webhooks, etc. | -| `messages` | [Messages Docs](/configuration/config/messages.mdx) | Customize messages shown to users. | -| `structured` | [Structured Output Docs](/configuration/config/structured-ouptput.mdx) | Customize how hyperglass handles structured output from devices. | -| `web` | [Web UI Docs](/configuration/config/web-ui.mdx) | Customize the look and feel of hyperglass's web UI. | - -## Caveats - -### Arista EOS - -For whatever reason, the tested version of Arista EOS does not supply certain details about routes in its JSON output when running commands `show ip bgp regex ` or `show ip bgp community `. Specifically, the the route's timestamp and any attached communities are not supplied. When these commands are used with Arista EOS, hyperglass sets the timestamp to the current time, and the community to an empty list. diff --git a/src/stale/hyperglass/docs/pages/configuration/config/_meta.tsx b/src/stale/hyperglass/docs/pages/configuration/config/_meta.tsx deleted file mode 100644 index c91b461..0000000 --- a/src/stale/hyperglass/docs/pages/configuration/config/_meta.tsx +++ /dev/null @@ -1,8 +0,0 @@ -export default { - "api-docs": "API Docs", - caching: "Caching", - logging: "Logging & Webhooks", - messages: "Messages", - "structured-output": "Structured Output", - "web-ui": "Web UI", -}; diff --git a/src/stale/hyperglass/docs/pages/configuration/config/api-docs.mdx b/src/stale/hyperglass/docs/pages/configuration/config/api-docs.mdx deleted file mode 100644 index a88dd43..0000000 --- a/src/stale/hyperglass/docs/pages/configuration/config/api-docs.mdx +++ /dev/null @@ -1,72 +0,0 @@ -## API Docs - -hyperglass automatically generates documentation for the REST API. The `docs` section allows users to customize the look, feel, and text used for the REST API documentation. - -| Parameter | Type | Default Value | Description | -| :----------------- | :------ | :----------------------------- | :---------------------------------------------------------------------------------------------- | -| `docs.base_url` | String | https://lg.example.com | Used for REST API samples. See the [demo](https://demo.hyperglass.dev/api/docs) for an example. | -| `docs.enable` | Boolean | `true` | Enable or disable the REST API documentation. | -| `docs.path` | String | /api/docs | Path to the REST API documentation. | -| `docs.title` | String | `site_title` API Documentation | API docs title. Uses the `site_title` parameter from the [global](#global) parameters. | -| `docs.description` | String | | API docs description. Appears below the title. | - -The documentation for API endpoints follow a common schema: - -- `devices` -- `info` -- `queries` -- `query` - -### Schema - -| Parameter | Type | Description | -| :------------ | :----- | :------------------------------------------------------------------------------- | -| `title` | String | API endpoint title, displayed as the header text above the API endpoint section. | -| `description` | String | API endpoint description, displayed inside each API endpoint section. | -| `summary` | String | API endpoint summary, displayed beside the API endpoint path. | - -### Parameters - -| Parameter | Default Value | -| :------------------------- | :------------------------------------------------------------------------------------------ | -| `docs.devices.title` | Devices | -| `docs.devices.description` | List of all devices/locations with associated identifiers, display names, networks, & VRFs. | -| `docs.devices.summary` | Devices List | -| `docs.info.title` | System Information | -| `docs.info.description` | General information about this looking glass. | -| `docs.info.summary` | System Information | -| `docs.queries.title` | Supported Queries | -| `docs.queries.description` | List of supported query types. | -| `docs.queries.summary` | Query Types | -| `docs.query.title` | Supported Query | -| `docs.query.description` | Request a query response per-location. | -| `docs.query.summary` | Query the Looking Glass | - -#### Example with Defaults - -```yaml filename="config.yaml" -docs: - base_url: https://lg.example.com - enable: true - mode: redoc - path: /api/docs - title: Beloved Hyperglass User Looking Glass API Documentation - description: null - # API Endpoints ↓ - devices: - title: Devices - description: List of all devices/locations with associated identifiers, display names, networks, & VRFs. - summary: Devices List - info: - title: System Information - description: General information about this looking glass. - summary: System Information - queries: - title: Supported Queries - description: List of supported query types. - summary: Query Types - query: - title: Supported Query - description: Request a query response per-location. - summary: Query the Looking Glass -``` diff --git a/src/stale/hyperglass/docs/pages/configuration/config/caching.mdx b/src/stale/hyperglass/docs/pages/configuration/config/caching.mdx deleted file mode 100644 index 839b8e1..0000000 --- a/src/stale/hyperglass/docs/pages/configuration/config/caching.mdx +++ /dev/null @@ -1,16 +0,0 @@ -## Cache - -hyperglass automatically caches responses to reduce the number of times devices are queried for the same information. - -| Parameter | Type | Default Value | Description | -| :---------------- | :------ | :------------ | :------------------------------------------------------------------------------ | -| `cache.timeout` | Number | 120 | Number of seconds for which to cache device responses. | -| `cache.show_text` | Boolean | True | If true, an indication that a user is viewing cached information will be shown. | - -### Example with Defaults - -```yaml filename="config.yaml" -cache: - timeout: 120 - show_text: true -``` diff --git a/src/stale/hyperglass/docs/pages/configuration/config/logging.mdx b/src/stale/hyperglass/docs/pages/configuration/config/logging.mdx deleted file mode 100644 index 5f1e834..0000000 --- a/src/stale/hyperglass/docs/pages/configuration/config/logging.mdx +++ /dev/null @@ -1,90 +0,0 @@ -## Logging - -Console, file, HTTP, and/or syslog logging configuration. - -| Parameter | Type | Default Value | Description | -| :---------- | :----- | :------------ | :---------------------------------------------- | -| `directory` | String | /tmp | Path to directory where logs will be created. | -| `format` | String | text | Log text format, must be `text` or `json`. | -| `max_size` | String | 50MB | Maximum log file size before being overwritten. | - -### Syslog - -| Parameter | Type | Default Value | Description | -| :-------- | :----- | :------------ | :---------------------- | -| `host` | String | | Syslog target host. | -| `port` | Number | 514 | Syslog target UDP port. | - -##### Syslog Example - -```yaml filename="config.yaml" copy -logging: - syslog: - host: log.example.com - port: 514 -``` - -### HTTP Logging - -If enabled, logs will be sent by HTTP `POST` method. - -| Parameter | Type | Default Value | Description | -| :----------- | :------ | :------------ | :---------------------------------------------- | -| `provider` | String | generic | Must be `generic`, `msteams`, or `slack`. | -| `host` | String | | URL | -| `headers` | Map | | | -| `params` | Map | | | -| `verify_ssl` | Boolean | true | Enable or disable SSL certificate verification. | -| `timeout` | Number | 5 | HTTP connection timeout in seconds. | - -#### Authentication - -Authentication is supported using HTTP basic authentication or an API key. - -| Parameter | Type | Default Value | Description | -| :----------------------------- | :----- | :------------ | :--------------------------------------------------------------------------------------------------------- | -| `http.authentication.mode` | String | basic | Must be `basic` or `api_key`. | -| `http.authentication.username` | String | | Basic authentication username if `mode` is set to `basic`. | -| `http.authentication.password` | String | | Basic authentication password if `mode` is set to `basic`, or API key value if `mode` is set to `api_key`. | -| `http.authentication.header` | String | X-API-Key | Header name if `mode` is set to `api_key`. | - -#### Examples - -##### Generic - -```yaml filename="config.yaml" copy -logging: - http: - provider: generic - host: https://httpbin.org - headers: - x-special-header: super special header value - params: - source: hyperglass - verify_ssl: true - timeout: 5 - authentication: - mode: basic - username: your username - password: super secret password -``` - -In the above example, hyperglass will send a `POST` request to `https://httpbin.org?source=hyperglass` with Basic Authentication headers set. - -##### Microsoft Teams Webhook - -```yaml filename="config.yaml" copy -logging: - http: - provider: msteams - host: -``` - -##### Slack - -```yaml filename="config.yaml" copy -logging: - http: - provider: slack - host: -``` diff --git a/src/stale/hyperglass/docs/pages/configuration/config/messages.mdx b/src/stale/hyperglass/docs/pages/configuration/config/messages.mdx deleted file mode 100644 index 135a788..0000000 --- a/src/stale/hyperglass/docs/pages/configuration/config/messages.mdx +++ /dev/null @@ -1,23 +0,0 @@ -## Message Customization - -hyperglass provides as much control over user-facing text/messages as possible. The following messages may be adjusted as needed: - -| Parameter | Type | Default Value | Description | -| :------------------------------ | :----- | :------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `messages.authentication_error` | String | Authentication error occurred. | Displayed when hyperglass is unable to authenticate to a device. Usually, this indicates a configuration error. | -| `messages.connection_error` | String | Error connecting to \{device_name\}: \{error\} | Displayed when hyperglass is unable to connect to a device. Usually, this indicates a configuration error. `{device_name}` and `{error}` will be used to display the device in question and the specific connection error. | -| `messages.general` | String | Something went wrong. | Displayed when errors occur that hyperglass didn't anticipate or handle correctly. Seeing this error message may indicate a bug in hyperglass. If you see this in the wild, try enabling [debug mode](#global) and review the logs to pinpoint the source of the error. | -| `messages.invalid_input` | String | \{target\} is not valid. | Displayed when a query target's value is invalid in relation to the corresponding query type. `{target}` will be used to display the invalid target. | -| `messages.invalid_query` | String | \{target\} is not a valid \{query_type\} target. | Displayed when a query target's value is invalid in relation to the corresponding query type. `{target}` and `{query_type}` may be used to display the invalid target and corresponding query type. | -| `messages.no_input` | String | \{field\} must be specified. | Displayed when a required field is not specified. `{field}` will be used to display the name of the field that was omitted. | -| `messages.no_output` | String | The query completed, but no matching results were found. | Displayed when hyperglass can connect to a device and execute a query, but the response is empty. | -| `messages.not_found` | String | \{type\} '\{name\}' not found. | Displayed when an object property does not exist in the configuration. `{type}` corresponds to a user-friendly name of the object type (for example, 'Device'), `{name}` corresponds to the object name that was not found. | -| `messages.request_timeout` | String | Request timed out. | Displayed when the [`request_timeout`](#global) time expires. | -| `messages.target_not_allowed` | String | \{target\} is not allowed. | Displayed when a query target is implicitly denied by a configured rule. `{target}` will be used to display the denied query target. | - -##### Example - -```yaml filename="config.yaml" -message: - general: Something with wrong. -``` diff --git a/src/stale/hyperglass/docs/pages/configuration/config/structured-output.mdx b/src/stale/hyperglass/docs/pages/configuration/config/structured-output.mdx deleted file mode 100644 index df93625..0000000 --- a/src/stale/hyperglass/docs/pages/configuration/config/structured-output.mdx +++ /dev/null @@ -1,61 +0,0 @@ -## Structured - -Devices that support responding to a query with structured or easily parsable data can have their response data placed into an easier to read table (or JSON, when using the REST API). Currently, the following platforms have structured data supported in hyperglass: - -- Arista EOS -- Juniper Junos - -When structured output is available, hyperglass checks the RPKI state of each BGP prefix returned using one of two methods: - -1. From the router's perspective -2. From the perspective of [Cloudflare's RPKI Service](https://rpki.cloudflare.com/) - -Additionally, hyperglass provides the ability to control which BGP communities are shown to the end user. - -| Parameter | Type | Default Value | Description | -| :----------------------------- | :-------------- | :------------ | :---------------------------------------------------------------------------------------------------------------------------- | -| `structured.rpki.mode` | String | router | Use `router` to use the router's view of the RPKI state (1 above), or `external` to use Cloudflare's view (2 above). | -| `structured.communities.mode` | String | deny | Use `deny` to deny any communities listed in `structured.communities.items`, or `permit` to _only_ permit communities listed. | -| `structured.communities.items` | List of Strings | | List of communities to match. | - -### RPKI Examples - -#### Show RPKI State from the Device's Perspective - -```yaml filename="config.yaml" copy {2} -structured: - rpki: - mode: router -``` - -#### Show RPKI State from a Public/External Perspective - -```yaml filename="config.yaml" copy {2} -structured: - rpki: - mode: external -``` - -### Community Filtering Examples - -#### Deny Listed Communities by Regex pattern - -```yaml filename="config.yaml" {5-6} -structured: - communities: - mode: deny - items: - - '^65000:1\d+$' # don't show any communities starting with 65000:1. 65000:1234 would be denied, but 65000:4321 would be permitted. - - "65000:2345" # don't show the 65000:2345 community. -``` - -#### Permit only Listed Communities - -```yaml filename="config.yaml" {5-6} -structured: - communities: - mode: permit - items: - - "^65000:.*$" # permit any communities starting with 65000, but no others. - - "1234:1" # permit only the 1234:1 community. -``` diff --git a/src/stale/hyperglass/docs/pages/configuration/config/web-ui.mdx b/src/stale/hyperglass/docs/pages/configuration/config/web-ui.mdx deleted file mode 100644 index 7613447..0000000 --- a/src/stale/hyperglass/docs/pages/configuration/config/web-ui.mdx +++ /dev/null @@ -1,294 +0,0 @@ -import { Callout } from "nextra/components"; -import { Color } from "~/components/color"; - -## Web UI - -hyperglass provides extensive customization options for the look and feel of the web UI. - -| Parameter | Type | Default Value | Description | -| :-------------------------- | :----- | :------------ | :----------------------------------------------------------------------------------------------------------------------------------------- | -| `web.location_display_mode` | String | auto | Show the locations field as a `dropdown`, `gallery`. When using `auto`, if there are more than 5 location groups, `dropdown` will be used. | -| `web.custom_javascript` | String | | Path to a javascript file that will be loaded with the website. | -| `web.custom_html` | String | | Path to a custom HTML file that will be loaded with the website and rendered beneath the app. | - -### DNS over HTTPS - -[DNS over HTTPS](https://www.rfc-editor.org/rfc/rfc8484) is used to look up an FQDN query target from the perspective of the user's browser. - -| Parameter | Type | Default Value | Description | -| :------------------ | :----- | :------------------------------------- | :-------------------------------------------------------------------------- | -| `dns_provider.name` | String | cloudflare | If `cloudflare` or `google` are provided, no URL is necessary. | -| `dns_provider.url` | String | `https://cloudflare-dns.com/dns-query` | Provide a custom DNS over HTTPS URL if you'd like to use your own resolver. | - -### Logo - -| Parameter | Type | Default Value | Description | -| :----------------- | :--------------- | :------------ | :------------------------------------------------- | -| `web.logo.light` | String | | Path to logo to show in light mode. | -| `web.logo.dark` | String | | Path to logo to show in dark mode. | -| `web.logo.favicon` | String | | Path to icon/logo from which to generate favicons. | -| `web.logo.width` | Number or String | 100% | Width of logo, either as pixels or a percentage. | -| `web.logo.height` | Number or String | | Height of logo, either as pixels or a percentage. | - -##### Example - -```yaml filename="config.yaml" copy -web: - logo: - light: /path/to/light-logo.svg - dark: /path/to/dark-logo.svg - favicon: /path/to/favicon.svg - width: 100% - height: null -``` - -### Greeting - -The greeting is an optional modal/popup window that will present itself to users in the Web UI. It can be used for anything you want; for example: - -- A data privacy acknowledgement that must be acknowledged prior to proceeding -- Information about your company -- Instructions on how to use hyperglass - -| Parameter | Type | Default Value | Description | -| :---------------------- | :------ | :------------ | :--------------------------------------------------------------------------------------------------- | -| `web.greeting.enable` | Boolean | False | Enable or disable the greeting. | -| `web.greeting.file` | String | | Path to markdown or plain text file that contains greeting content. | -| `web.greeting.title` | String | Welcome | Text to be used as the greeting title. | -| `web.greeting.button` | String | Continue | Text to be used for the button that acknowledges/closes the greeting. | -| `web.greeting.required` | Boolean | False | If `true`, users cannot close the modal or run any queries until the greeting has been acknowledged. | - -##### Example - -```yaml filename="config.yaml" copy -web: - greeting: - enable: true - file: /path/to/your/file.md - title: Welcome - button: Continue - required: false -``` - -### OpenGraph - -[OpenGraph](https://ogp.me/) is the thing that generates the pretty pictures, titles, and descriptions for links when you post them to sites/tools such as Facebook, Twitter, Slack, etc. By default, [this Opengraph image](/opengraph.jpg) is used, but you can provide your own image. You don't need to worry about sizing or formatting it properly, hyperglass will handle this for you. - -| Parameter | Type | Default Value | Description | -| :-------------------- | :----- | :------------ | :---------------------------- | -| `web.opengraph.image` | String | | Path to your OpenGraph image. | - -### Highlighting - -hyperglass can highlight special values in your router output and provide users with additional information about the content. For example, your organization's BGP communities or IP address space can be visually highlighted, and a tooltip can be shown when a user hovers over the highlighted value. - -Each value you wish to be highlighted is defined with the following schema: - -| Parameter | Type | Default Value | Description | -| :-------- | :----- | :------------ | :------------------------------------------------------ | -| `pattern` | String | | RegEx pattern or string to match against router output. | -| `label` | String | | Tooltip value when the highlighted text is hovered. | -| `color` | String | | Color name from [`web.theme.colors`](#colors). | - -##### Example - -```yaml filename="config.yaml" copy -web: - highlight: - - pattern: "65000:1234" - label: Special snowflake community that does a thing - color: primary - - pattern: '^192\.0\.2\.[0-9]+$' - label: Magical IP Address - color: blue -``` - -### Menus - -hyperglass can show completely-customizable menus in the footer. Each menu can be configured with the following schema: - -| Parameter | Type | Default Value | Description | -| :-------- | :----- | :------------ | :------------------------------------------------------------------------------------------------------------------------- | -| `title` | String | | Menu title, will be the text that shows on footer. | -| `content` | String | | Plain text or markdown content of the menu or path to a file that contains plain text or markdown content. | -| `side` | String | left | Side of the footer with which the menu will be grouped. | -| `order` | Number | 0 | Optionally specify an order for each menu item. If not specified, menus will be rendered in the order they are configured. | - -##### Example - -```yaml filename="config.yaml" copy -web: - menus: - - title: Terms & Conditions - content: - | **Don't** break stuff! - _please_ - side: right - order: 1 - - title: Help - content: /path/to/help/file.md - side: left - order: 0 -``` - -### Links - -hyperglass can show customizable links to anything you think your users might find helpful. Each link can be configured with the following schema: - -| Parameter | Type | Default Value | Description | -| :---------- | :------ | :------------ | :-------------------------------------------------------------------------------------------------------------------- | -| `title` | String | | Link text. | -| `url` | String | | Link URL. | -| `show_icon` | Boolean | True | If `true`, an icon indicating the link is an external link is shown. | -| `side` | String | left | Side of the footer with which the link will be grouped. | -| `order` | Number | 0 | Optionally specify an order for each link. If not specified, links will be rendered in the order they are configured. | - -##### Example - -```yaml filename="config.yaml" copy -web: - links: - - title: PeeringDB - url: https://www.peeringdb.com/65000 - show_icon: true - side: right - order: 1 - - title: Our Website - url: https://example.com - show_icon: false - side: left - order: 0 -``` - -### Credit - -| Parameter | Type | Default | Description | -| :-------- | :-----: | :-----: | :--------------------------------------------------------------------------------------- | -| `enable` | Boolean | `true` | Enable or disable the display of developer credit & link to hyperglass GitHub repository | - - - **Note from the Developer** -
If your organization's policy allows, and you don't mind, I request that you keep `credit` - enabled. Remember: my goal for this project is get more networks to use looking glasses to make all - of our lives easier. Because it's primarily other network operators who will use this tool to begin - with, I'd love for any operators that use your looking glass to know where they can get their own. -
- -### Text - -Most of the text in the hyperglass UI can be overridden to suit your needs. - -| Parameter | Type | Default Value | Description | -| :--------------------------- | :----- | :------------------------------------ | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `web.text.title_mode` | String | logo_only | See [title mode section](#title-mode) | -| `web.text.title` | String | hyperglass | Title text. | -| `web.text.subtitle` | String | Network Looking Glass | Subtitle text. | -| `web.text.query_location` | String | Location | Text used to label the query location (router) field. | -| `web.text.query_type` | String | Query Type | Text used to label the query type (directive) field. | -| `web.text.query_target` | String | Target | Text used to label the query target field. | -| `web.text.fqdn_tooltip` | String | Use \{protocol\} | Tooltip text used when a user hovers over the FQDN tooltip. | -| `web.text.fqdn_message` | String | Your browser has resolved \{fqdn\} to | Text used when prompting a user to select a resolve IPv4 or IPv6 address for an FQDN query. | -| `web.text.fqdn_error` | String | Unable to resolve \{fqdn\} | Text used when an FQDN is not resolvable. | -| `web.text.fqdn_error_button` | String | Try Again | Button text used when an FQDN is not resolvable. | -| `web.text.cache_prefix` | String | Results cached for | Text displayed with the cache timeout countdown. | -| `web.text.cache_icon` | String | Cached from \{time\} UTC | Text used when a user hovers over the cache icon, which is displayed when a response was a cached response. `{time}` is replaced with the _original_ query's timestamp. | -| `web.text.complete_time` | String | Completed in \{seconds\} | Text used when a user hovers over the success icon for a query result. `{seconds}` will be replaced with 'n seconds' where n is the time a query took to complete. | -| `web.text.rpki_invalid` | String | Invalid | Text used in table output when a route's RPKI status is invalid. | -| `web.text.rpki_valid` | String | Valid | Text used in table output when a route's RPKI status is valid. | -| `web.text.rpki_unknown` | String | No ROAs Exist | Text used in table output when a route's RPKI status is unknown. | -| `web.text.rpki_unverified` | String | Not Verified | Text used in table output when a route's RPKI status is unverified. | -| `web.text.no_communities` | String | No Communities | Text used in table output when a route has no communities. | -| `web.text.ip_error` | String | Unable to determine IP Address | Error displayed if hyperglass is unable to determine the user's IP. | -| `web.text.no_ip` | String | No \{protocol\} Address | Text displayed if the user doesn't have an IP address of \{protocol\} (IPv4 or IPv6). | -| `web.text.ip_select` | String | Select an IP Address | Text used to label the IP Address selection for the user's IP. | -| `web.text.ip_button` | String | My IP | Text used for the user IP button. | - -#### Title Mode - -Available title modes are: - -| `title_mode` Value | Action | -| :----------------- | :------------------------------------------------------------------ | -| `logo_only` | Only the logo is displayed, no title or subtitle will be visible. | -| `text_only` | Only the title and subtitle are displayed, no logo will be visible. | -| `logo_subtitle` | Only the logo and subtitle are displayed, no title will be visible. | -| `all` | Logo, title, and subtitle will all be visible. | - -##### Example - -```yaml filename="config.yaml" -web: - text: - title: Our Looking Glass - subtitle: Company Name, Inc. - title_mode: text_only -``` - -### Theme - -hyperglass allows you to customize the colors and fonts used in the Web UI. - -| Parameter | Type | Default Value | Description | -| :----------------------------- | :----- | :------------ | :--------------------------------------------------------------------------------------------------------------- | -| `web.theme.default_color_mode` | String | | Set hyperglass's default color mode. By default, the user's system preference is used. Must be `light` or `dark` | - -#### Colors - -##### Intrinsic Colors - -| Parameter | Default Value | -| :------------------------ | :---------------------- | -| `web.theme.colors.black` | | -| `web.theme.colors.white` | | -| `web.theme.colors.dark` | | -| `web.theme.colors.light` | | -| `web.theme.colors.gray` | | -| `web.theme.colors.red` | | -| `web.theme.colors.orange` | | -| `web.theme.colors.yellow` | | -| `web.theme.colors.green` | | -| `web.theme.colors.blue` | | -| `web.theme.colors.teal` | | -| `web.theme.colors.cyan` | | -| `web.theme.colors.pink` | | -| `web.theme.colors.purple` | | - -##### Functional Colors - -| Parameter | Default Value | -| :--------------------------- | :--------------------- | -| `web.theme.colors.primary` | | -| `web.theme.colors.secondary` | | -| `web.theme.colors.success` | | -| `web.theme.colors.warning` | | -| `web.theme.colors.error` | | -| `web.theme.colors.danger` | | - -###### Example - -To override hyperglass's primary color, it's recommended to override its mapped intrinsic color. For example, to override the default primary color to cyan: - -```yaml filename="config.yaml" -web: - theme: - colors: - cyan: "#00ffff" -``` - -#### Fonts - -hyperglass's fonts are loaded from [Google Fonts](https://fonts.google.com/). Any Google font name may be specified to override the default fonts. - -| Parameter | Type | Default Value | Description | -| :--------------------- | :----- | :------------ | :--------------------------------------------------------------------------------------- | -| `web.theme.fonts.body` | String | Nunito | Font for all standard body text, including headings. | -| `web.theme.fonts.mono` | String | Fire Code | Font for all monospace text such as inline code or code blocks, including device output. | - -##### Example - -```yaml filename="config.yaml" -web: - theme: - fonts: - body: Inter -``` diff --git a/src/stale/hyperglass/docs/pages/configuration/devices.mdx b/src/stale/hyperglass/docs/pages/configuration/devices.mdx deleted file mode 100644 index f30799a..0000000 --- a/src/stale/hyperglass/docs/pages/configuration/devices.mdx +++ /dev/null @@ -1,135 +0,0 @@ -import { Callout } from "nextra/components"; -import { SupportedPlatforms } from "~/components/platforms"; -import { DocsButton } from "~/components/docs-button"; - -## Device Configuration Parameters - -Each configured device may have the following parameters: - -| Parameter | Type | Default Value | Description | -| :------------------ | :-------------- | :------------ | :----------------------------------------------------------------------------------------------------------------------------------------- | -| `name` | String | | Display name of the device. | -| `description` | String | | Description of the device, displayed as a subtle label. | -| `avatar` | String | | Path to an avatar/logo image for this site. Used when [`web.location_display_mode`](/configuration/config/web-ui.mdx) is set to `gallery`. | -| `address` | String | | IPv4 address, IPv6 address, or hostname of the device. | -| `group` | String | | Group name, used to visually group devices in the UI. | -| `port` | Number | | TCP port on which to connect to the device. | -| `platform` | String | | Device platform/OS. Must be a [supported platform](/platforms.mdx). | -| `structured_output` | Boolean | True | Disable structured output for a device that supports it. | -| `directives` | List of Strings | | Enable referenced directives configured in the [directives config file](/configuration/directives.mdx). | -| `driver` | String | netmiko | Specify which driver to use for this device. Currently, only `netmiko` is supported. | -| `driver_config` | Mapping | | Mapping/dict of options to pass to the connection driver. | -| `attrs` | Mapping | | Mapping/dict of variables, as referenced in configured directives. | -| `credential` | Mapping | | Mapping/dict of a [credential configuration](/configuration/devices/credentials.mdx). | -| `http` | Mapping | | Mapping/dict of [HTTP client options](/configuration/devices/http-device.mdx), if this device is connected via HTTP. | -| `proxy` | Mapping | | Mapping/dict of [SSH proxy config](/configuration/devices/ssh-proxy.mdx) to use for this device's requests. | - - - -hyperglass ships with predefined [directives](/configuration/directives.mdx) (commands) for the following [platforms](platforms.mdx): - - - -All built in directives require that the following `attrs` be defined on each device using the directive: - -| Attribute | Value | -| :-------- | :-------------------------------------------------------- | -| `source4` | IPv4 address used to source Ping and Traceroute commands. | -| `source6` | IPv6 address used to source Ping and Traceroute commands. | - -**Example** - -```yaml filename="devices.yaml" {5-7} copy -devices: - - name: New York, NY - address: 192.0.2.1 - platform: cisco_ios - attrs: - source4: 192.0.2.1 - source6: "2001:db8::1" -``` - - - - - If you do not utilize IPv6 in your network, you'll need to create your own directive that only - has IPv4 commands. - - -## Examples - -### Simple - -```yaml filename="devices.yaml" copy -devices: - - name: New York, NY - address: 192.0.2.1 - platform: cisco_ios - credential: - username: you - password: your password - - name: San Francisco, CA - address: 192.0.2.2 - platform: juniper - credential: - username: you - password: your password -``` - -

- {" "} - With Directives -

- -In this example, an additional directive `cisco-show-lldp-neighbors` is added to the built-in directives. - -```yaml filename="devices.yaml" copy {8-9} -devices: - - name: New York, NY - address: 192.0.2.1 - platform: cisco_ios - credential: - username: you - password: your password - directives: - - cisco-show-lldp-neighbors -``` - -

- {" "} - Disable Built-in Directives -

- -In this example, _only_ the `cisco-show-lldp-neighbors` directive will be available. Built-in directives are disabled. - -```yaml filename="devices.yaml" copy {8-10} -devices: - - name: New York, NY - address: 192.0.2.1 - platform: cisco_ios - credential: - username: you - password: your password - directives: - - builtin: false - - cisco-show-lldp-neighbors -``` - -

- {" "} - Enable Specifc Built-in Directives -

- -In this example, only specified built-in directives are made available. - -```yaml filename="devices.yaml" copy {8-9} -devices: - - name: New York, NY - address: 192.0.2.1 - platform: cisco_ios - credential: - username: you - password: your password - directives: - - builtin: [bgp_route, traceroute] -``` diff --git a/src/stale/hyperglass/docs/pages/configuration/devices/_meta.tsx b/src/stale/hyperglass/docs/pages/configuration/devices/_meta.tsx deleted file mode 100644 index cc95490..0000000 --- a/src/stale/hyperglass/docs/pages/configuration/devices/_meta.tsx +++ /dev/null @@ -1,5 +0,0 @@ -export default { - credentials: "Credentials", - "http-device": "HTTP Device", - "ssh-proxy": "SSH Proxy", -}; diff --git a/src/stale/hyperglass/docs/pages/configuration/devices/credentials.mdx b/src/stale/hyperglass/docs/pages/configuration/devices/credentials.mdx deleted file mode 100644 index 463ff68..0000000 --- a/src/stale/hyperglass/docs/pages/configuration/devices/credentials.mdx +++ /dev/null @@ -1,35 +0,0 @@ -Each device must be configured with credentials with which hyperglass can log into the device and execute commands. - -## Credential Configuration - -| Parameter | Type | Default Value | Description | -| :-------------------- | :----- | :------------ | :----------------------------------------------------- | -| `credential.username` | String | | Username to use for authentication to the device. | -| `credential.password` | String | | Password to use for authentication to the device. | -| `credential.key` | String | | Path to SSH key used for authentication to the device. | - -### Examples - -#### Username & Password - -```yaml filename="devices.yaml" copy {5-7} -devices: - - name: New York, NY - address: 192.0.2.1 - platform: cisco_ios - credential: - username: you - password: your password -``` - -#### SSH Private Key - -```yaml filename="devices.yaml" copy {5-7} -devices: - - name: San Francisco, CA - address: 192.0.2.2 - platform: juniper - credential: - username: you - key: /path/to/your/ssh/key -``` diff --git a/src/stale/hyperglass/docs/pages/configuration/devices/http-device.mdx b/src/stale/hyperglass/docs/pages/configuration/devices/http-device.mdx deleted file mode 100644 index ce14abe..0000000 --- a/src/stale/hyperglass/docs/pages/configuration/devices/http-device.mdx +++ /dev/null @@ -1,85 +0,0 @@ -hyperglass supports collecting output from a generic HTTP endpoint. - -## HTTP Configuration - -| Parameter | Type | Default Value | Description | -| :---------------------- | :------ | :------------ | :--------------------------------------------------------------------------------------------------------------------- | -| `http.attribute_map` | Mapping | | Mapping/dict of hyperglass query fields as keys, and hyperglass query field replacements as values. | -| `http.basic_auth` | Mapping | | If basic authentication is required, provide a mapping/dict containing the basic authentication username and password. | -| `http.body_format` | String | json | Body format, options are `json` `yaml` `xml` `text` | -| `http.follow_redirects` | Boolean | `false` | Follow HTTP redirects from server. | -| `http.headers` | Mapping | | Mapping/dict of http headers to append to requests. | -| `http.method` | String | GET | HTTP method to use for requests. | -| `http.path` | String | / | HTTP URI/Path. | -| `http.query` | Mapping | | Mapping/Dict of URL Query Parameters. | -| `http.retries` | Number | 0 | Number of retries to perform before request failure. | -| `http.scheme` | String | https | HTTP schema, must be `http` or `https` | -| `http.source` | String | | Request source IP address. | -| `http.ssl_ca` | String | | Path to SSL CA certificate file for SSL validation. | -| `http.ssl_client` | String | | Path to client SSL certificates for request. | -| `http.timeout` | Number | 5 | Request timeout in seconds. | -| `http.verify_ssl` | Boolean | `true` | If `false`, invalid certificates for HTTPS hosts will be ignored. | - -### Example - -#### Basic - -The following example will send an HTTP POST request to `https://192.0.2/path/to/query/device` with HTTP basic authentication, and will not verify the SSL certificate. - -```yaml filename="devices.yaml" copy -devices: - - name: New York, NY - address: 192.0.2.1 - http: - path: /path/to/query/device - method: POST - verify_ssl: false - basic_auth: - username: you - password: your password -``` - -Given the following hyperglass query: - -| Field | Value | -| :------------- | :------------------ | -| Query Target | `192.0.2.0/24` | -| Query Location | `your_location` | -| Query Type | `example_directive` | - -The body of the request will be: - -```json -{ - "query_target": "192.0.2.0/24", - "query_location": "your_location", - "query_type": "example_directive" -} -``` - -#### Non-HTTPS Request - -The following example will send an HTTP GET request to `http://192.0.2.1/path/to/query/device`: - -```yaml filename="devices.yaml" {6} copy -devices: - - name: New York, NY - address: 192.0.2.1 - http: - path: /path/to/query/device - scheme: http -``` - -#### Header Authentication - -The following example will send an HTTP GET request to `https://192.0.2.1/path/to/query/device` with an `Authorization` header: - -```yaml filename="devices.yaml" {6-7} copy -devices: - - name: New York, NY - address: 192.0.2.1 - http: - path: /path/to/query/device - headers: - Authorization: your special token -``` diff --git a/src/stale/hyperglass/docs/pages/configuration/devices/ssh-proxy.mdx b/src/stale/hyperglass/docs/pages/configuration/devices/ssh-proxy.mdx deleted file mode 100644 index 99d19f1..0000000 --- a/src/stale/hyperglass/docs/pages/configuration/devices/ssh-proxy.mdx +++ /dev/null @@ -1,30 +0,0 @@ -In cases where access to the devices is secured behind a "jump box" or other intermediary server/device, hyperglass can use SSH local port forwarding to SSH to an intermedary device first, and then to the device. - -## SSH Proxy Configuration - -| Parameter | Type | Default Value | Description | -| :----------------- | :------ | :------------ | :----------------------------------------------------------------------------------- | -| `proxy.address` | String | | IPv4 address, IPv6 address, or hostname of SSH proxy. | -| `proxy.port` | Number | 22 | TCP port to use for connecting to the SSH proxy. | -| `proxy.platform` | String | linux_ssh | Currently, only `linux_ssh` is supported. | -| `proxy.credential` | Mapping | | Mapping/dict of a [credential configuration](/configuration/config/credentials.mdx). | - -### Examples - -#### Use an SSH Proxy When Connecting to a Device - -```yaml filename="devices.yaml" copy -devices: - - name: New York, NY - address: 192.0.2.1 - credential: - username: you - password: your password - proxy: - address: 203.0.113.1 - credential: - username: your proxy username - password: your proxy password -``` - -In the above example, the credentials `your proxy username`/`your proxy password` will be used to authenticate from the hyperglass server to the SSH proxy, and the credentials `you`/`your password` will be used to authentiate from the SSH proxy to the device. diff --git a/src/stale/hyperglass/docs/pages/configuration/directives.mdx b/src/stale/hyperglass/docs/pages/configuration/directives.mdx deleted file mode 100644 index 9da3812..0000000 --- a/src/stale/hyperglass/docs/pages/configuration/directives.mdx +++ /dev/null @@ -1,188 +0,0 @@ -import { Callout } from "nextra/components"; - -## What is a directive? - - - -A directive is a defined configuration for one or more **commands** to run on a device. For example, a BGP Route query is a built-in directive. A directive defines: - -- What command (or commands) to run on the device -- Type of UI field, text input or select -- If the field can accept multiple values -- Help information to show about the directive -- Validation rules - - - -Each directive has the following options: - -| Parameter | Type | Default Value | Description | -| :------------------- | :-------------- | :------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `name` | String | | Display name of the directive. | -| `rules` | List of Rules | | List of [rule configs](#rules) | -| `field` | Mapping | | Mapping/dict of [fields config](#fields) | -| `info` | String | | File path to markdown-formatted help information about the directive. | -| `plugins` | List of Strings | | List of plugin names to use with this directive. | -| `groups` | List of Strings | | List of names by which directives are grouped in the UI. | -| `multiple` | Boolean | `false` | Command supports receiving multiple values. For example, Cisco IOS's `show ip bgp community` accepts multiple communities as arguments. | -| `multiple_separator` | String | `" "` | String by which multiple values are separated. For example, a list of values `[65001, 65002, 65003]` would be rendered as `65001 65002 65003` for when the command is run. | - -## Rules - -A rule is a way of saying "if a query target matches the rule's conditions, run this command". - -| Parameter | Type | Default Value | Description | -| :---------- | :-------------- | :------------ | :--------------------------------------------------------------------------------------------- | -| `condition` | String | | Regular expression to match or IP prefix in which the value being evaluated must be contained. | -| `action` | String | permit | `permit` or `deny` the directive target when this rule is matched. | -| `commands` | List of Strings | | Commands to run when this rule matches. `{target}` is replaced with the query target. | - -### IP Rule - -| Parameter | Type | Default Value | Description | -| :------------------ | :------ | :------------ | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `ge` | Number | 0 | Prefix length greater than defined will be matched. | -| `le` | Number | 32,128 | `32` for IPv4 evaluations, `128` for IPv6 evaluations. Prefix length less than defined will be matched. | -| `allow_reserved` | Boolean | `false` | Allow reserved ([RFC1918](https://www.rfc-editor.org/rfc/rfc1918), [RFC5735](https://www.rfc-editor.org/rfc/rfc5735), [RFC5737](https://www.rfc-editor.org/rfc/rfc5737.html), etc.) addresses to pass validation. | -| `allow_unspecified` | Boolean | `false` | Allow unspecified addresses (`0.0.0.0` `::`) to pass validation. | -| `allow_loopback` | Boolean | `false` | Allow [loopback addresses](https://www.rfc-editor.org/rfc/rfc1700.html) (`127.0.0.0/8` `::1`) to pass validation. | - -#### Examples - -##### Require IPv4 Queries between /8 and /24 - -```yaml filename="directives.yaml" {5-6} /{target} {mask}/ copy -your-directive: - name: IP Route - rules: - - condition: 0.0.0.0/0 - ge: 8 - le: 24 - command: "show ip route {target} {mask}" -``` - -Given a query target of 198.18.0.0/15, the command run on the device would be: - -```none /198.18.0.0 255.254.0.0/ -show ip route 198.18.0.0 255.254.0.0 -``` - -##### Deny a Specific Prefix - -```yaml filename="directives.yaml" {5} copy -your directive: - name: BGP Route - rules: - - condition: "192.0.2.0/24" - action: deny - - condition: "0.0.0.0/0" - command: "show ip bgp {target}" -``` - -In this example, a query of any IP address or prefix contained within 192.0.2.0/24 will result in an error. - -##### Run Multiple Commands - -```yaml filename="directives.yaml" /{target}/ {6-7} copy -your-directive: - name: BGP Communities - rules: - - condition: "65000:[0-9]+" - commands: - - "show route table inet.0 community {target} detail" - - "show route table inet6.0 community {target} detail" -``` - -In this example, a query of `65000:1` would result in the following commands being sent to the device: - -```none /65000:1/ -show route table inet.0 community 65000:1 detail -show route table inet6.0 community 65000:1 detail -``` - -The output for both commands will be shown as the query result. - -### Regex Validation - -To validate input by regex pattern, just specify a regex pattern as the `condition` - -```yaml filename="directives.yaml" copy -your-directive: - name: DNS Query - rules: - - condition: '^.+\.yourdomain\.com$' -``` - -### No Validation - -```yaml filename="directives.yaml" /{target}/ copy {4} -your-directive: - name: IP Route - rules: - - condition: null - command: show ip route {target} -``` - -In this example, any query would pass, regardless of query input. For instance, if a user selected this directive/query type and queried `your mom`, the real command sent to the device will be: - -```none /your mom/ -show ip route your mom -``` - -## Fields - -### Text Input - -| Parameter | Type | Default Value | Description | -| :------------ | :----- | :------------ | :---------------------------------------------------- | -| `description` | String | | Field description, displayed as a label or help text. | -| `validation` | String | | Regex pattern to validate text input. | - -### Select - -| Parameter | Type | Default Value | Description | -| :------------ | :-------------- | :------------ | :---------------------------------------------------- | -| `description` | String | | Field description, displayed as a label or help text. | -| `options` | List of Options | | | - -#### Options - -Each select option uses the following schema: - -| Parameter | Type | Default Value | Description | -| :------------ | :----- | :------------ | :------------------------------------------------------- | -| `description` | String | | Field description, displayed as a label or help text. | -| `name` | String | | If specified, will be used as the option's display name. | -| `value` | String | | Option value sent to the device. | - -### Examples - -Example of a text directive expecting a string value matching a regex pattern: - -```yaml filename="directives.yaml" copy {6-7} -your-directive: - name: IP Route - rules: - - condition: null - command: show ip route {target} - field: - description: IP of target - validation: '[0-9a-f\.\:]+' -``` - -Example of a select directive: - -```yaml filename="directives.yaml" copy {6-12} -your-directive: - name: BGP Community - rules: - - condition: null - command: show ip bgp community {target} - field: - description: BGP community to show - options: - - value: "65001:1" - description: Provider A Routes - - value: "65001:2" - description: Provider B Routes -``` diff --git a/src/stale/hyperglass/docs/pages/configuration/examples/_meta.tsx b/src/stale/hyperglass/docs/pages/configuration/examples/_meta.tsx deleted file mode 100644 index d415124..0000000 --- a/src/stale/hyperglass/docs/pages/configuration/examples/_meta.tsx +++ /dev/null @@ -1,5 +0,0 @@ -export default { - "basic-configuration": "Basic Configuration", - "add-your-own-command": "Add Your Own Command", - "customize-the-ui": "Customize the UI", -}; diff --git a/src/stale/hyperglass/docs/pages/configuration/examples/add-your-own-command.mdx b/src/stale/hyperglass/docs/pages/configuration/examples/add-your-own-command.mdx deleted file mode 100644 index a8f588a..0000000 --- a/src/stale/hyperglass/docs/pages/configuration/examples/add-your-own-command.mdx +++ /dev/null @@ -1,60 +0,0 @@ -import { Steps } from "nextra/components"; - -## Add Your Own Command - -While hyperglass does come with several built-in [directives](/configuration/configuration/directives.mdx) (commands), you can also add your own. For example, say you want to add a command that shows the BGP summary from a device: - - - -### Create the Directive - -```yaml filename="directives.yaml" copy -show-bgp-summary: - name: BGP Summary - rules: - - condition: null - command: show bgp all summary - field: null -``` - -### Associate the Directive with the Device - -```yaml filename="devices.yaml" {5-6} copy -devices: - - name: Your Router - address: 192.0.2.1 - platform: cisco_ios - directives: - - show-bgp-summary -``` - - - -## Default Directives - -By default, all built-in directives are _also_ enabled. If you wish to _only_ enable directives you specify, you can use `builtins: false` as a directive: - -```yaml filename="devices.yaml" {6-7} copy -devices: - - name: Your Router - address: 192.0.2.1 - platform: cisco_ios - directives: - - builtins: false - - show-bgp-summary -``` - -In the above example, _only_ the `show-bgp-summary` directive will be enabled. - -You can also selectively enable certain built-in directives: - -```yaml filename="devices.yaml" {6} copy -devices: - - name: Your Router - address: 192.0.2.1 - platform: cisco_ios - directives: - - builtins: [bgp_route, traceroute] -``` - -In the above example, _only_ the BGP Route and Traceroute built-in directives will be enabled. diff --git a/src/stale/hyperglass/docs/pages/configuration/examples/basic-configuration.mdx b/src/stale/hyperglass/docs/pages/configuration/examples/basic-configuration.mdx deleted file mode 100644 index c7e64c5..0000000 --- a/src/stale/hyperglass/docs/pages/configuration/examples/basic-configuration.mdx +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: Basic Configuration -description: Get started with a basic hyperglass configuration ---- - -import { Callout } from "nextra/components"; - -To get started, hyperglass only needs to know about your devices. - - - **Devices** are your routers, switches, or whatever else you want to call the endpoints - hyperglass will query for information. - - -## Simple Device Configuration - -```yaml filename="devices.yaml" -devices: - - name: NYC Router 1 - address: - credential: - username: - password: - platform: cisco_ios - attrs: - source4: - source6: -``` - -That's it! diff --git a/src/stale/hyperglass/docs/pages/configuration/examples/customize-the-ui.mdx b/src/stale/hyperglass/docs/pages/configuration/examples/customize-the-ui.mdx deleted file mode 100644 index 24e564a..0000000 --- a/src/stale/hyperglass/docs/pages/configuration/examples/customize-the-ui.mdx +++ /dev/null @@ -1,60 +0,0 @@ ---- -description: Customize hyperglass to fit your needs. ---- - -import { DocsButton } from "~/components/docs-button"; - -

- {" "} - Change the Title and Organization Name -

- -```yaml filename="config.yaml" -site_title: Our super neat looking glass -org_name: Cool Company -``` - -

- {" "} - Change the Logo -

- -```yaml filename="config.yaml" {2-4} copy -web: - logo: - light: - dark: -``` - -

- {" "} - Change the Color Scheme -

- -```yaml filename="config.yaml" copy {3-5} -web: - theme: - colors: - primary: "#d84b4b" - secondary: "#118ab2" -``` - -

- {" "} - Add a Link to the Footer -

- -```yaml filename="config.yaml" copy -web: - links: - - title: PeeringDB - url: https://www.peeringdb.com/65000 - show_icon: true - side: right - order: 1 - - title: Our Website - url: https://example.com - show_icon: false - side: left - order: 0 -``` diff --git a/src/stale/hyperglass/docs/pages/configuration/overview.mdx b/src/stale/hyperglass/docs/pages/configuration/overview.mdx deleted file mode 100644 index c90c4dc..0000000 --- a/src/stale/hyperglass/docs/pages/configuration/overview.mdx +++ /dev/null @@ -1,76 +0,0 @@ -import { Code, Table, Td, Th, Tr, Callout } from "nextra/components"; -import { SupportedPlatforms } from "~/components/platforms"; - -Once you've gotten started with a basic configuration, you'll probably want to customize the look and feel of hyperglass by changing the logo or color scheme. Fortunately, there are _a lot_ ways to customize hyperglass. - -## Configuration Files - -| File Name | Docs | Purpose | -| :----------- | :---------------------------------------------------: | :------------------------------------------------------------------------- | -| `config` | [Config File Docs](/configuration/config.mdx) | Application-wide configuration such as logging, web UI customization, etc. | -| `devices` | [Devices File Docs](/configuration/devices.mdx) | Your devices and their associated configurations. | -| `directives` | [Directives File Docs](/configuration/directives.mdx) | Custom directives (commands). | - - - **File Extensions**
- All the examples in the docs are provided in [YAML](https://yaml.org/) format, but [TOML](https://toml.io/), - JSON, and Python files are also supported. -
- -### Using a Python File - -When using a Python file for a hyperglass configuration, one of the following methods may be used: - -#### Define a Function Named `main` - -```python filename="Example: Using a Python function to define configuration parameters" -def main(): - return { - "org_name": "Your Organization Name", - "web": { - "theme": { - "colors": { - "blue": "#0000ff", - } - } - } - } - -# The main function can also be an async function. -async def main(): - config = await some_function_to_fetch_config() - return config -``` - -#### Define a Dictionary Named `main` - -```python filename="Example: Using a Python dictionary to define configuration parameters" -main = { - "org_name": "Your Organization Name", - "web": { - "theme": { - "colors": { - "blue": "#0000ff", - } - } - } - } -``` - -## Built-in Directives - -hyperglass ships with predefined [directives](/configuration/directives.mdx) for the following [platforms](platforms.mdx): - - - -All built in directives require that the following `attrs` be defined on each device using the directive: - -| Attribute | Value | -| :-------- | :-------------------------------------------------------- | -| `source4` | IPv4 address used to source Ping and Traceroute commands. | -| `source6` | IPv6 address used to source Ping and Traceroute commands. | - - - If you do not utilize IPv6 in your network, you'll need to create your own directive that only - has IPv4 commands. - diff --git a/src/stale/hyperglass/docs/pages/index.mdx b/src/stale/hyperglass/docs/pages/index.mdx deleted file mode 100644 index d12892f..0000000 --- a/src/stale/hyperglass/docs/pages/index.mdx +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: Introduction -description: Get started with hyperglass ---- - -import { Cards } from "nextra/components"; -import { SupportedPlatforms } from "~/components/platforms"; - -## What is hyperglass? - -hyperglass is an open source network looking glass written -by a network engineer for other network engineers. The purpose of a looking glass is to provide customers, -peers, and complete strangers with unattended visibility into the an operator's network. - -hyperglass was created with the lofty goal of benefiting the internet community at-large by providing a faster, easier, and more secure way for operators to provide looking glass services to their customers, peers, and other network operators. - -## Features - -- BGP Route, BGP Community, BGP AS Path, Ping, & Traceroute -- Full IPv6 support -- Customizable everything: features, theme, UI/API text, error messages, commands -- Built in support for: - -- Configurable support for any other [supported platform](platforms.mdx) -- Optionally access devices via an SSH proxy/jump server -- VRF support -- Access List/prefix-list style query control to whitelist or blacklist query targets on a per-VRF basis -- REST API with automatic, configurable OpenAPI documentation -- Modern, responsive UI -- Query multiple devices simultaneously -- Browser-based DNS-over-HTTPS resolution of FQDN queries - - - - diff --git a/src/stale/hyperglass/docs/pages/installation.mdx b/src/stale/hyperglass/docs/pages/installation.mdx deleted file mode 100644 index 0eb736a..0000000 --- a/src/stale/hyperglass/docs/pages/installation.mdx +++ /dev/null @@ -1,11 +0,0 @@ -import { Cards } from "nextra/components"; - - - - - - - - - - diff --git a/src/stale/hyperglass/docs/pages/installation/_meta.tsx b/src/stale/hyperglass/docs/pages/installation/_meta.tsx deleted file mode 100644 index 6f531ec..0000000 --- a/src/stale/hyperglass/docs/pages/installation/_meta.tsx +++ /dev/null @@ -1,7 +0,0 @@ -export default { - docker: "Using Docker", - manual: "Manual Installation", - "environment-variables": "Environment Variables", - "reverse-proxy": "Reverse Proxy", - upgrading: "Upgrading hyperglass", -}; diff --git a/src/stale/hyperglass/docs/pages/installation/docker.mdx b/src/stale/hyperglass/docs/pages/installation/docker.mdx deleted file mode 100644 index cab3e31..0000000 --- a/src/stale/hyperglass/docs/pages/installation/docker.mdx +++ /dev/null @@ -1,60 +0,0 @@ ---- -title: Using Docker -description: Installing hyperglass with Docker ---- - -import { Cards, Steps, Callout } from "nextra/components"; -// import { Callout } from "nextra-theme-docs"; - -**Docker is the recommended method for running hyperglass.** - - - -### Install Docker - - - - - -### Download hyperglass - -```shell copy -mkdir /etc/hyperglass -cd /opt -git clone https://github.com/thatmattlove/hyperglass.git --depth=1 -cd /opt/hyperglass -``` - -### Optional: Quickstart - -Do this if you just want to see the hyperglass page working with a fake device. - -```shell copy -cp /opt/hyperglass/.samples/sample_devices.yaml /etc/hyperglass/devices.yaml -cd /opt/hyperglass -docker compose up -``` - -Navigate to http://localhost:8001 - -### Create a `systemd` service - - - Before you create and start the hyperglass service, you may want to verify whether or not you - intend to change any [environment variables](environment-variables.mdx) and change them first. - - -```shell copy -cp /opt/hyperglass/.samples/hyperglass-docker.service /etc/hyperglass/hyperglass.service -ln -s /etc/hyperglass/hyperglass.service /etc/systemd/system/hyperglass.service -systemctl daemon-reload -systemctl enable hyperglass -systemctl start hyperglass -``` - - diff --git a/src/stale/hyperglass/docs/pages/installation/environment-variables.mdx b/src/stale/hyperglass/docs/pages/installation/environment-variables.mdx deleted file mode 100644 index 64d3915..0000000 --- a/src/stale/hyperglass/docs/pages/installation/environment-variables.mdx +++ /dev/null @@ -1,22 +0,0 @@ ---- -title: Environment Variables -description: hyperglass environment variables ---- - -There are some configuration variables that must be supplied before hyperglass can start or read its configuration files. Most of the time, you should not need to modify these. - -Environment variables may be overridden at the command line, or by placing them in `${HYPERGLASS_APP_PATH}/hyperglass.env`. - -| Variable Name | Type | Default | Description | -| :-------------------------- | :------ | :---------------- | :----------------------------------------------------------------------------------------------------------------- | -| `HYPERGLASS_DEBUG` | boolean | `false` | Enable debug logging | -| `HYPERGLASS_DEV_MODE` | boolean | `false` | Enable developer mode. This should only be used if you are developing hyperglass under specific circumstances. | -| `HYPERGLASS_DISABLE_UI` | boolean | `false` | If set to `true`, the hyperglass UI is not built or served. The only way to access hyperglass is via REST API. | -| `HYPERGLASS_APP_PATH` | string | `/etc/hyperglass` | Directory where hyperglass configuration files and static web UI files are contained. | -| `HYPERGLASS_REDIS_HOST` | string | `localhost` | Host on which Redis is running. | -| `HYPERGLASS_REDIS_PASSWORD` | string | — | Redis password, if any. | -| `HYPERGLASS_REDIS_DB` | number | `1` | Redis database number. | -| `HYPERGLASS_REDIS_DSN` | string | — | Redis DSN. If supplied, overrides `HYPERGLASS_REDIS_HOST`, `HYPERGLASS_REDIS_DB`, and `HYPERGLASS_REDIS_PASSWORD`. | -| `HYPERGLASS_HOST` | string | `[::1]` | Address on which hyperglass listens for requests. | -| `HYPERGLASS_PORT` | number | `8001` | TCP port on which hyperglass listens for requests. | -| `HYPERGLASS_CA_CERT` | string | — | Path to CA certificate file for validating HTTPS certificates. If not supplied, system CAs are used. | diff --git a/src/stale/hyperglass/docs/pages/installation/manual.mdx b/src/stale/hyperglass/docs/pages/installation/manual.mdx deleted file mode 100644 index 4c3cefc..0000000 --- a/src/stale/hyperglass/docs/pages/installation/manual.mdx +++ /dev/null @@ -1,68 +0,0 @@ ---- -title: Manual Installation -description: Installing hyperglass manually ---- - -import { Steps, Callout } from "nextra/components"; - - - -### Install Dependencies - -To install hyperglass manually, you'll need to install the following dependencies: - -1. [Python 3.11, or 3.12](https://www.python.org/downloads/) and [`pip`](https://pip.pypa.io/en/stable/installation/) -2. [NodeJS 20.14 or later](https://nodejs.org/en/download) -3. [PNPM 9 or later](https://pnpm.io/installation) -4. [Redis 7.2 or later](https://redis.io/download/) - -Make sure the Redis server is started. - -### Install hyperglass - -Once these dependencies are installed, install hyperglass via PyPI: - -```shell copy -git clone https://github.com/thatmattlove/hyperglass --depth=1 -cd hyperglass -# optional - switch to the latest stable release -# git switch -c v2.0.4 v2.0.4 -pip3 install -e . -``` - -### Create app directory - - - If you plan on using a different directory, be sure to set the directory you wish to use in your - [environment variables](environment-variables.mdx). - - -```shell copy -mkdir /etc/hyperglass -``` - -### Optional: Quickstart - -Do this if you just want to see the hyperglass page working with default settings and a fake device. - -```shell copy -curl -o /etc/hyperglass/devices.yaml https://raw.githubusercontent.com/thatmattlove/hyperglass/main/.samples/sample_devices.yaml -hyperglass start -``` - -### Create a `systemd` service - -```shell copy -curl -o /etc/hyperglass/hyperglass.service https://raw.githubusercontent.com/thatmattlove/hyperglass/main/.samples/hyperglass-manual.service -ln -s /etc/hyperglass/hyperglass.service /etc/systemd/system/hyperglass.service -systemctl daemon-reload -systemctl enable hyperglass -systemctl start hyperglass -``` - - - If you used a different app directory from the default `/etc/hyperglass`, change the - `EnvironmentFile` value in the `hyperglass.service` file. - - - diff --git a/src/stale/hyperglass/docs/pages/installation/reverse-proxy.mdx b/src/stale/hyperglass/docs/pages/installation/reverse-proxy.mdx deleted file mode 100644 index aa821f6..0000000 --- a/src/stale/hyperglass/docs/pages/installation/reverse-proxy.mdx +++ /dev/null @@ -1,44 +0,0 @@ ---- -title: Reverse Proxy -description: Setting up a reverse proxy for hyperglass ---- - -import { Cards, Callout } from "nextra/components"; - -[Caddy](https://caddyserver.com) is recommended, but any reverse proxy ([NGINX](https://www.nginx.com), [Apache2](https://httpd.apache.org)) will work. - -## Caddy - - - - - -```shell copy -cp /opt/hyperglass/.samples/Caddyfile /etc/caddy/Caddyfile -``` - -Change the `lg.example.com` and `person@example.com` values to match your hyperglass FQDN and email address (the email address is for automatic SSL certificate generation via Let's Encrypt). - - - If you prefer to use other Let's Encrypt validation methods or your own SSL certificate, modify - your `/etc/hyperglass/Caddyfile` in accordance with the [Caddy - docs](https://caddyserver.com/docs/caddyfile-tutorial). - - -Restart the Caddy service: `systemctl restart caddy{:shell}` - -## NGINX - -```shell copy -cp /opt/hyperglass/.samples/hyperglass.nginx /etc/nginx/sites-available/hyperglass -ln -s /etc/nginx/sites-available/hyperglass /etc/nginx/sites-enabled/hyperglass -``` - -Change the `lg.example.com` value to match your hyperglass FQDN. - -Change the `` and `` values to match the path to your certificate and private key files. diff --git a/src/stale/hyperglass/docs/pages/installation/upgrading.mdx b/src/stale/hyperglass/docs/pages/installation/upgrading.mdx deleted file mode 100644 index f70da5e..0000000 --- a/src/stale/hyperglass/docs/pages/installation/upgrading.mdx +++ /dev/null @@ -1,11 +0,0 @@ -## Using Docker - -```shell copy -cd /opt/hyperglass -docker compose down -docker compose rm -f -git fetch -git checkout v2.0.4 -docker compose build -docker compose up -``` diff --git a/src/stale/hyperglass/docs/pages/license.mdx b/src/stale/hyperglass/docs/pages/license.mdx deleted file mode 100644 index 7d80c0f..0000000 --- a/src/stale/hyperglass/docs/pages/license.mdx +++ /dev/null @@ -1,20 +0,0 @@ -# The Clear BSD License - -export const Year = () => new Date().getFullYear(); - -**Copyright © Matthew Love** - -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, are permitted (subject to the limitations in the disclaimer below) provided that the following conditions are met: - -- Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -- Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from this - software without specific prior written permission. - -> NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/stale/hyperglass/docs/pages/platforms.mdx b/src/stale/hyperglass/docs/pages/platforms.mdx deleted file mode 100644 index 365cb17..0000000 --- a/src/stale/hyperglass/docs/pages/platforms.mdx +++ /dev/null @@ -1,28 +0,0 @@ ---- -description: Platforms supported by hyperglass ---- - -import { Callout } from "nextra/components"; -import { PlatformTable } from "~/components/platforms"; - -hyperglass uses [Netmiko](https://github.com/ktbyers/netmiko) to interact with devices via SSH/telnet. [All platforms supported by Netmiko](https://github.com/ktbyers/netmiko/blob/develop/PLATFORMS.md) are supported by hyperglass. - -## Netmiko Platforms - - - Just because Netmiko supports a given platform doesn't mean it will automatically work with - hyperglass. hyperglass has a limited number of built in directives (listed below). Any platforms - other than the ones listed below will require you to [add a custom - directive](configuration/examples/add-your-own-command.mdx) for each command you wish to make - available. - - -
- - - -## Other Platforms - -| Platform | Key | Natively Supported | -| :---------------- | :----- | :------------------------------------------------------------------: | -| Any HTTP Endpoint | `http` | [See HTTP Device Docs](configuration/devices.mdx#http-configuration) | diff --git a/src/stale/hyperglass/docs/pages/plugins.mdx b/src/stale/hyperglass/docs/pages/plugins.mdx deleted file mode 100644 index adc5087..0000000 --- a/src/stale/hyperglass/docs/pages/plugins.mdx +++ /dev/null @@ -1,144 +0,0 @@ ---- -title: Plugins -description: hyperglass Plugins ---- - -import { Cards, Card } from "nextra/components"; - -Starting in version 2.0, hyperglass supports custom plugins. There are two main types of plugins: - -- [**Input Plugins**](#input-plugins): Apply custom validation logic to or transform user input before the query is sent to a device. -- [**Output Plugins**](#output-plugins): Interact with the output from a device before it's displayed to the user. - -Plugins are associated with a directive. - -## Examples - -### Input Plugins - -#### Convert a CIDR Prefix to Network and Mask - -In this example, the following query is sent to hyperglass: - -```json filename="Example Query" -{ - "query_target": "192.0.2.0/24", - "query_location": "your_location", - "query_type": "ip_route_directive" -} -``` - -The below plugin is defined and referenced by a directive: - -```python filename="/path/to/your/transform_plugin.py" -from ipaddress import ip_network -from hyperglass.plugins import InputPlugin - - -class TransformCIDR(InputPlugin): - def transform(self, query): - (target := query.query_target) - target_network = ip_network(target) - if target_network.version == 4: - return f"{target_network.network_address!s} {target_network.netmask!s}" - return target -``` - -```yaml filename="directives.yaml" -ip_route_directive: - name: IP Route - plugins: - - "/path/to/your/transform_plugin.py" - rules: - - condition: "0.0.0.0/0" - action: permit - command: "show ip route {target}" - - condition: "::/0" - action: permit - command: "show ipv6 route {target}" -``` - -When the query is received, the query target is transformed, resulting in this being sent to the device: - -```text -show ip route 192.0.2.0 255.255.255.0 -``` - -instead of: - -```text -show ip route 192.0.2.0/24 -``` - -#### Validate User Input - -In this example, we want to perform some custom validation not available via the directives `condition` API. For instance, say you wanted to ensure a query target isn't contained within a dynamic list of [bogon prefixes from Team Cymru](https://www.team-cymru.com/bogon-networks). - -```python filename="/path/to/your/validation_plugin.py" -from ipaddress import ip_network - -from hyperglass.plugins import InputPlugin -from hyperglass.external import HTTPClient - -class BogonPlugin(InputPlugin): - def validate(self, query): - target = ip_network(query.query_target) - - with HTTPClient(base_url="https://team-cymru.org") as client: - response = client.get("/Services/Bogons/fullbogons-ipv4.txt") - - bogon_strings = [line.strip() for line in response.text.split("\n") if not line.startswith("#")] - bogons = [ip_network(bogon) for bogon in bogon_strings] - - for bogon in bogons: - if target in bogon or target == bogon: - return False # Return false to fail validation. - return True -``` - -This isn't the best real-world example, since the above plugin would be run on every request, likely resulting in slow query responses, but it illustrates the power of plugins. - -### Output Plugins - -#### Redact Sensitive Information - -Say one of your directives might show some sensitive information in the query output. Using an output plugin, we can replace any text matching a pattern (or multiple patterns) with some other text. - -```python -import re -from hyperglass.plugins import OutputPlugin - -SENSITIVE_PATTERN = re.compile("SuperSecretInfo") - -class Redact(OutputPlugin): - def process(self, output, query): - result = [] - for each_output in output: - redacted = SENSITIVE_PATTERN.sub("", each_output) - result.append(redacted) - return result -``` - -If the query output was: - -```text -Lorem ipsum dolor sit amet, SuperSecretInfo consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. -Viverra suspendisse potenti nullam ac. At elementum eu facilisis sed odio morbi. SuperSecretInfo iaculis urna id volutpat lacus.Nisl nisi -scelerisque eu ultrices vitae. Accumsan SuperSecretInfo tortor posuere ac ut consequat semper viverra nam libero. Libero id faucibus nisl -tincidunt eget nullam non nisi. Et ligula ullamcorper malesuada SuperSecretInfo proin libero nunc. Et malesuada fames ac turpis egestas sed. -Nulla facilisi cras fermentum odio eu. SuperSecretInfo condimentum mattis pellentesque id nibh tortor id aliquet lectus proin. Nisl rhoncus -mattis rhoncus urna neque. Tortor aliquam nulla facilisi cras SuperSecretInfo fermentum odio eu feugiat. Neque egestas congue quisque egestas -diam in arcu cursus SuperSecretInfo. -``` - -The above plugin would transform the output to: - -```text -Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. -Viverra suspendisse potenti nullam ac. At elementum eu facilisis sed odio morbi. iaculis urna id volutpat lacus.Nisl nisi -scelerisque eu ultrices vitae. Accumsan tortor posuere ac ut consequat semper viverra nam libero. Libero id faucibus nisl -tincidunt eget nullam non nisi. Et ligula ullamcorper malesuada proin libero nunc. Et malesuada fames ac turpis egestas sed. -Nulla facilisi cras fermentum odio eu. condimentum mattis pellentesque id nibh tortor id aliquet lectus proin. Nisl rhoncus -mattis rhoncus urna neque. Tortor aliquam nulla facilisi cras fermentum odio eu feugiat. Neque egestas congue quisque egestas -diam in arcu cursus . -``` diff --git a/src/stale/hyperglass/docs/platforms.json b/src/stale/hyperglass/docs/platforms.json deleted file mode 100644 index 43164ab..0000000 --- a/src/stale/hyperglass/docs/platforms.json +++ /dev/null @@ -1 +0,0 @@ -[{"name": "Arista EOS", "keys": ["arista_eos"], "native": true}, {"name": "BIRD", "keys": ["bird"], "native": true}, {"name": "Cisco IOS", "keys": ["cisco_ios"], "native": true}, {"name": "Cisco NX-OS", "keys": ["cisco_nxos"], "native": true}, {"name": "Cisco IOS-XR", "keys": ["cisco_xr"], "native": true}, {"name": "FRRouting", "keys": ["frr"], "native": true}, {"name": "Huawei VRP", "keys": ["huawei", "huawei_vrpv8"], "native": true}, {"name": "Juniper Junos", "keys": ["juniper", "juniper_junos"], "native": true}, {"name": "Mikrotik", "keys": ["mikrotik_routeros", "mikrotik_switchos"], "native": true}, {"name": "Nokia SR OS", "keys": ["nokia_sros"], "native": true}, {"name": "OpenBGPD", "keys": ["openbgpd"], "native": true}, {"name": "TNSR", "keys": ["tnsr"], "native": true}, {"name": "VyOS", "keys": ["vyos"], "native": true}, {"name": "", "keys": ["a10"], "native": false}, {"name": "", "keys": ["a10_ssh"], "native": false}, {"name": "", "keys": ["accedian"], "native": false}, {"name": "", "keys": ["accedian_ssh"], "native": false}, {"name": "", "keys": ["adtran_os"], "native": false}, {"name": "", "keys": ["adtran_os_ssh"], "native": false}, {"name": "", "keys": ["adtran_os_telnet"], "native": false}, {"name": "", "keys": ["alcatel_aos"], "native": false}, {"name": "", "keys": ["alcatel_aos_ssh"], "native": false}, {"name": "", "keys": ["alcatel_sros"], "native": false}, {"name": "", "keys": ["alcatel_sros_ssh"], "native": false}, {"name": "", "keys": ["allied_telesis_awplus"], "native": false}, {"name": "", "keys": ["allied_telesis_awplus_ssh"], "native": false}, {"name": "", "keys": ["apresia_aeos"], "native": false}, {"name": "", "keys": ["apresia_aeos_ssh"], "native": false}, {"name": "", "keys": ["apresia_aeos_telnet"], "native": false}, {"name": "", "keys": ["arista_eos_ssh"], "native": false}, {"name": "", "keys": ["arista_eos_telnet"], "native": false}, {"name": "", "keys": ["aruba_os"], "native": false}, {"name": "", "keys": ["aruba_os_ssh"], "native": false}, {"name": "", "keys": ["aruba_osswitch"], "native": false}, {"name": "", "keys": ["aruba_osswitch_ssh"], "native": false}, {"name": "", "keys": ["aruba_procurve"], "native": false}, {"name": "", "keys": ["aruba_procurve_ssh"], "native": false}, {"name": "", "keys": ["aruba_procurve_telnet"], "native": false}, {"name": "", "keys": ["audiocode_66"], "native": false}, {"name": "", "keys": ["audiocode_66_ssh"], "native": false}, {"name": "", "keys": ["audiocode_66_telnet"], "native": false}, {"name": "", "keys": ["audiocode_72"], "native": false}, {"name": "", "keys": ["audiocode_72_ssh"], "native": false}, {"name": "", "keys": ["audiocode_72_telnet"], "native": false}, {"name": "", "keys": ["audiocode_shell"], "native": false}, {"name": "", "keys": ["audiocode_shell_ssh"], "native": false}, {"name": "", "keys": ["audiocode_shell_telnet"], "native": false}, {"name": "", "keys": ["autodetect"], "native": false}, {"name": "", "keys": ["avaya_ers"], "native": false}, {"name": "", "keys": ["avaya_ers_ssh"], "native": false}, {"name": "", "keys": ["avaya_vsp"], "native": false}, {"name": "", "keys": ["avaya_vsp_ssh"], "native": false}, {"name": "", "keys": ["broadcom_icos"], "native": false}, {"name": "", "keys": ["broadcom_icos_ssh"], "native": false}, {"name": "", "keys": ["brocade_fastiron"], "native": false}, {"name": "", "keys": ["brocade_fastiron_ssh"], "native": false}, {"name": "", "keys": ["brocade_fastiron_telnet"], "native": false}, {"name": "", "keys": ["brocade_fos"], "native": false}, {"name": "", "keys": ["brocade_fos_ssh"], "native": false}, {"name": "", "keys": ["brocade_netiron"], "native": false}, {"name": "", "keys": ["brocade_netiron_ssh"], "native": false}, {"name": "", "keys": ["brocade_netiron_telnet"], "native": false}, {"name": "", "keys": ["brocade_nos"], "native": false}, {"name": "", "keys": ["brocade_nos_ssh"], "native": false}, {"name": "", "keys": ["brocade_vdx"], "native": false}, {"name": "", "keys": ["brocade_vdx_ssh"], "native": false}, {"name": "", "keys": ["brocade_vyos"], "native": false}, {"name": "", "keys": ["brocade_vyos_ssh"], "native": false}, {"name": "", "keys": ["calix_b6"], "native": false}, {"name": "", "keys": ["calix_b6_ssh"], "native": false}, {"name": "", "keys": ["calix_b6_telnet"], "native": false}, {"name": "", "keys": ["cdot_cros"], "native": false}, {"name": "", "keys": ["cdot_cros_ssh"], "native": false}, {"name": "", "keys": ["centec_os"], "native": false}, {"name": "", "keys": ["centec_os_ssh"], "native": false}, {"name": "", "keys": ["centec_os_telnet"], "native": false}, {"name": "", "keys": ["checkpoint_gaia"], "native": false}, {"name": "", "keys": ["checkpoint_gaia_ssh"], "native": false}, {"name": "", "keys": ["ciena_saos"], "native": false}, {"name": "", "keys": ["ciena_saos_ssh"], "native": false}, {"name": "", "keys": ["ciena_saos_telnet"], "native": false}, {"name": "", "keys": ["cisco_asa"], "native": false}, {"name": "", "keys": ["cisco_asa_ssh"], "native": false}, {"name": "", "keys": ["cisco_ftd"], "native": false}, {"name": "", "keys": ["cisco_ftd_ssh"], "native": false}, {"name": "", "keys": ["cisco_ios_serial"], "native": false}, {"name": "", "keys": ["cisco_ios_ssh"], "native": false}, {"name": "", "keys": ["cisco_ios_telnet"], "native": false}, {"name": "", "keys": ["cisco_nxos_ssh"], "native": false}, {"name": "", "keys": ["cisco_s300"], "native": false}, {"name": "", "keys": ["cisco_s300_ssh"], "native": false}, {"name": "", "keys": ["cisco_s300_telnet"], "native": false}, {"name": "", "keys": ["cisco_tp"], "native": false}, {"name": "", "keys": ["cisco_tp_ssh"], "native": false}, {"name": "", "keys": ["cisco_viptela"], "native": false}, {"name": "", "keys": ["cisco_viptela_ssh"], "native": false}, {"name": "", "keys": ["cisco_wlc"], "native": false}, {"name": "", "keys": ["cisco_wlc_ssh"], "native": false}, {"name": "", "keys": ["cisco_xe"], "native": false}, {"name": "", "keys": ["cisco_xe_ssh"], "native": false}, {"name": "", "keys": ["cisco_xr_ssh"], "native": false}, {"name": "", "keys": ["cisco_xr_telnet"], "native": false}, {"name": "", "keys": ["cloudgenix_ion"], "native": false}, {"name": "", "keys": ["cloudgenix_ion_ssh"], "native": false}, {"name": "", "keys": ["coriant"], "native": false}, {"name": "", "keys": ["coriant_ssh"], "native": false}, {"name": "", "keys": ["dell_dnos6_telnet"], "native": false}, {"name": "", "keys": ["dell_dnos9"], "native": false}, {"name": "", "keys": ["dell_dnos9_ssh"], "native": false}, {"name": "", "keys": ["dell_force10"], "native": false}, {"name": "", "keys": ["dell_force10_ssh"], "native": false}, {"name": "", "keys": ["dell_isilon"], "native": false}, {"name": "", "keys": ["dell_isilon_ssh"], "native": false}, {"name": "", "keys": ["dell_os10"], "native": false}, {"name": "", "keys": ["dell_os10_ssh"], "native": false}, {"name": "", "keys": ["dell_os6"], "native": false}, {"name": "", "keys": ["dell_os6_ssh"], "native": false}, {"name": "", "keys": ["dell_os9"], "native": false}, {"name": "", "keys": ["dell_os9_ssh"], "native": false}, {"name": "", "keys": ["dell_powerconnect"], "native": false}, {"name": "", "keys": ["dell_powerconnect_ssh"], "native": false}, {"name": "", "keys": ["dell_powerconnect_telnet"], "native": false}, {"name": "", "keys": ["dell_sonic"], "native": false}, {"name": "", "keys": ["dell_sonic_ssh"], "native": false}, {"name": "", "keys": ["dlink_ds"], "native": false}, {"name": "", "keys": ["dlink_ds_ssh"], "native": false}, {"name": "", "keys": ["dlink_ds_telnet"], "native": false}, {"name": "", "keys": ["eltex"], "native": false}, {"name": "", "keys": ["eltex_esr"], "native": false}, {"name": "", "keys": ["eltex_esr_ssh"], "native": false}, {"name": "", "keys": ["eltex_ssh"], "native": false}, {"name": "", "keys": ["endace"], "native": false}, {"name": "", "keys": ["endace_ssh"], "native": false}, {"name": "", "keys": ["enterasys"], "native": false}, {"name": "", "keys": ["enterasys_ssh"], "native": false}, {"name": "", "keys": ["ericsson_ipos"], "native": false}, {"name": "", "keys": ["ericsson_ipos_ssh"], "native": false}, {"name": "", "keys": ["extreme"], "native": false}, {"name": "", "keys": ["extreme_ers"], "native": false}, {"name": "", "keys": ["extreme_ers_ssh"], "native": false}, {"name": "", "keys": ["extreme_exos"], "native": false}, {"name": "", "keys": ["extreme_exos_ssh"], "native": false}, {"name": "", "keys": ["extreme_exos_telnet"], "native": false}, {"name": "", "keys": ["extreme_netiron"], "native": false}, {"name": "", "keys": ["extreme_netiron_ssh"], "native": false}, {"name": "", "keys": ["extreme_netiron_telnet"], "native": false}, {"name": "", "keys": ["extreme_nos"], "native": false}, {"name": "", "keys": ["extreme_nos_ssh"], "native": false}, {"name": "", "keys": ["extreme_slx"], "native": false}, {"name": "", "keys": ["extreme_slx_ssh"], "native": false}, {"name": "", "keys": ["extreme_ssh"], "native": false}, {"name": "", "keys": ["extreme_telnet"], "native": false}, {"name": "", "keys": ["extreme_tierra"], "native": false}, {"name": "", "keys": ["extreme_tierra_ssh"], "native": false}, {"name": "", "keys": ["extreme_vdx"], "native": false}, {"name": "", "keys": ["extreme_vdx_ssh"], "native": false}, {"name": "", "keys": ["extreme_vsp"], "native": false}, {"name": "", "keys": ["extreme_vsp_ssh"], "native": false}, {"name": "", "keys": ["extreme_wing"], "native": false}, {"name": "", "keys": ["extreme_wing_ssh"], "native": false}, {"name": "", "keys": ["f5_linux"], "native": false}, {"name": "", "keys": ["f5_linux_ssh"], "native": false}, {"name": "", "keys": ["f5_ltm"], "native": false}, {"name": "", "keys": ["f5_ltm_ssh"], "native": false}, {"name": "", "keys": ["f5_tmsh"], "native": false}, {"name": "", "keys": ["f5_tmsh_ssh"], "native": false}, {"name": "", "keys": ["flexvnf"], "native": false}, {"name": "", "keys": ["flexvnf_ssh"], "native": false}, {"name": "", "keys": ["fortinet"], "native": false}, {"name": "", "keys": ["fortinet_ssh"], "native": false}, {"name": "", "keys": ["generic"], "native": false}, {"name": "", "keys": ["generic_ssh"], "native": false}, {"name": "", "keys": ["generic_telnet"], "native": false}, {"name": "", "keys": ["generic_termserver"], "native": false}, {"name": "", "keys": ["generic_termserver_ssh"], "native": false}, {"name": "", "keys": ["generic_termserver_telnet"], "native": false}, {"name": "", "keys": ["hp_comware"], "native": false}, {"name": "", "keys": ["hp_comware_ssh"], "native": false}, {"name": "", "keys": ["hp_comware_telnet"], "native": false}, {"name": "", "keys": ["hp_procurve"], "native": false}, {"name": "", "keys": ["hp_procurve_ssh"], "native": false}, {"name": "", "keys": ["hp_procurve_telnet"], "native": false}, {"name": "", "keys": ["huawei_olt"], "native": false}, {"name": "", "keys": ["huawei_olt_ssh"], "native": false}, {"name": "", "keys": ["huawei_olt_telnet"], "native": false}, {"name": "", "keys": ["huawei_smartax"], "native": false}, {"name": "", "keys": ["huawei_smartax_ssh"], "native": false}, {"name": "", "keys": ["huawei_ssh"], "native": false}, {"name": "", "keys": ["huawei_telnet"], "native": false}, {"name": "", "keys": ["huawei_vrpv8_ssh"], "native": false}, {"name": "", "keys": ["ipinfusion_ocnos"], "native": false}, {"name": "", "keys": ["ipinfusion_ocnos_ssh"], "native": false}, {"name": "", "keys": ["ipinfusion_ocnos_telnet"], "native": false}, {"name": "", "keys": ["juniper_junos_ssh"], "native": false}, {"name": "", "keys": ["juniper_junos_telnet"], "native": false}, {"name": "", "keys": ["juniper_screenos"], "native": false}, {"name": "", "keys": ["juniper_screenos_ssh"], "native": false}, {"name": "", "keys": ["juniper_ssh"], "native": false}, {"name": "", "keys": ["keymile"], "native": false}, {"name": "", "keys": ["keymile_nos"], "native": false}, {"name": "", "keys": ["keymile_nos_ssh"], "native": false}, {"name": "", "keys": ["keymile_ssh"], "native": false}, {"name": "", "keys": ["linux"], "native": false}, {"name": "", "keys": ["linux_ssh"], "native": false}, {"name": "", "keys": ["mellanox"], "native": false}, {"name": "", "keys": ["mellanox_mlnxos"], "native": false}, {"name": "", "keys": ["mellanox_mlnxos_ssh"], "native": false}, {"name": "", "keys": ["mellanox_ssh"], "native": false}, {"name": "", "keys": ["mikrotik_routeros_ssh"], "native": false}, {"name": "", "keys": ["mikrotik_switchos_ssh"], "native": false}, {"name": "", "keys": ["mrv_lx"], "native": false}, {"name": "", "keys": ["mrv_lx_ssh"], "native": false}, {"name": "", "keys": ["mrv_optiswitch"], "native": false}, {"name": "", "keys": ["mrv_optiswitch_ssh"], "native": false}, {"name": "", "keys": ["netapp_cdot"], "native": false}, {"name": "", "keys": ["netapp_cdot_ssh"], "native": false}, {"name": "", "keys": ["netgear_prosafe"], "native": false}, {"name": "", "keys": ["netgear_prosafe_ssh"], "native": false}, {"name": "", "keys": ["netscaler"], "native": false}, {"name": "", "keys": ["netscaler_ssh"], "native": false}, {"name": "", "keys": ["nokia_srl"], "native": false}, {"name": "", "keys": ["nokia_srl_ssh"], "native": false}, {"name": "", "keys": ["nokia_sros_ssh"], "native": false}, {"name": "", "keys": ["nokia_sros_telnet"], "native": false}, {"name": "", "keys": ["oneaccess_oneos"], "native": false}, {"name": "", "keys": ["oneaccess_oneos_ssh"], "native": false}, {"name": "", "keys": ["oneaccess_oneos_telnet"], "native": false}, {"name": "", "keys": ["ovs_linux"], "native": false}, {"name": "", "keys": ["ovs_linux_ssh"], "native": false}, {"name": "", "keys": ["paloalto_panos"], "native": false}, {"name": "", "keys": ["paloalto_panos_ssh"], "native": false}, {"name": "", "keys": ["paloalto_panos_telnet"], "native": false}, {"name": "", "keys": ["pluribus"], "native": false}, {"name": "", "keys": ["pluribus_ssh"], "native": false}, {"name": "", "keys": ["quanta_mesh"], "native": false}, {"name": "", "keys": ["quanta_mesh_ssh"], "native": false}, {"name": "", "keys": ["rad_etx"], "native": false}, {"name": "", "keys": ["rad_etx_ssh"], "native": false}, {"name": "", "keys": ["rad_etx_telnet"], "native": false}, {"name": "", "keys": ["raisecom_roap"], "native": false}, {"name": "", "keys": ["raisecom_roap_ssh"], "native": false}, {"name": "", "keys": ["raisecom_telnet"], "native": false}, {"name": "", "keys": ["ruckus_fastiron"], "native": false}, {"name": "", "keys": ["ruckus_fastiron_ssh"], "native": false}, {"name": "", "keys": ["ruckus_fastiron_telnet"], "native": false}, {"name": "", "keys": ["ruijie_os"], "native": false}, {"name": "", "keys": ["ruijie_os_ssh"], "native": false}, {"name": "", "keys": ["ruijie_os_telnet"], "native": false}, {"name": "", "keys": ["sixwind_os"], "native": false}, {"name": "", "keys": ["sixwind_os_ssh"], "native": false}, {"name": "", "keys": ["sophos_sfos"], "native": false}, {"name": "", "keys": ["sophos_sfos_ssh"], "native": false}, {"name": "", "keys": ["supermicro_smis"], "native": false}, {"name": "", "keys": ["supermicro_smis_ssh"], "native": false}, {"name": "", "keys": ["supermicro_smis_telnet"], "native": false}, {"name": "", "keys": ["terminal_server"], "native": false}, {"name": "", "keys": ["tplink_jetstream"], "native": false}, {"name": "", "keys": ["tplink_jetstream_ssh"], "native": false}, {"name": "", "keys": ["tplink_jetstream_telnet"], "native": false}, {"name": "", "keys": ["ubiquiti_edge"], "native": false}, {"name": "", "keys": ["ubiquiti_edge_ssh"], "native": false}, {"name": "", "keys": ["ubiquiti_edgerouter"], "native": false}, {"name": "", "keys": ["ubiquiti_edgerouter_ssh"], "native": false}, {"name": "", "keys": ["ubiquiti_edgeswitch"], "native": false}, {"name": "", "keys": ["ubiquiti_edgeswitch_ssh"], "native": false}, {"name": "", "keys": ["ubiquiti_unifiswitch"], "native": false}, {"name": "", "keys": ["ubiquiti_unifiswitch_ssh"], "native": false}, {"name": "", "keys": ["vyatta_vyos"], "native": false}, {"name": "", "keys": ["vyatta_vyos_ssh"], "native": false}, {"name": "", "keys": ["vyos_ssh"], "native": false}, {"name": "", "keys": ["watchguard_fireware"], "native": false}, {"name": "", "keys": ["watchguard_fireware_ssh"], "native": false}, {"name": "", "keys": ["yamaha"], "native": false}, {"name": "", "keys": ["yamaha_ssh"], "native": false}, {"name": "", "keys": ["yamaha_telnet"], "native": false}, {"name": "", "keys": ["zte_zxros"], "native": false}, {"name": "", "keys": ["zte_zxros_ssh"], "native": false}, {"name": "", "keys": ["zte_zxros_telnet"], "native": false}, {"name": "", "keys": ["zyxel_os"], "native": false}, {"name": "", "keys": ["zyxel_os_ssh"], "native": false}] \ No newline at end of file diff --git a/src/stale/hyperglass/docs/pnpm-lock.yaml b/src/stale/hyperglass/docs/pnpm-lock.yaml deleted file mode 100644 index 9585e0d..0000000 --- a/src/stale/hyperglass/docs/pnpm-lock.yaml +++ /dev/null @@ -1,3554 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -importers: - - .: - dependencies: - next: - specifier: ^14.1.1 - version: 14.1.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - nextra: - specifier: 3.0.0-alpha.24 - version: 3.0.0-alpha.24(@types/react@18.0.26)(next@14.1.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.3.3) - nextra-theme-docs: - specifier: 3.0.0-alpha.24 - version: 3.0.0-alpha.24(next@14.1.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(nextra@3.0.0-alpha.24(@types/react@18.0.26)(next@14.1.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.3.3))(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - react: - specifier: ^18.2.0 - version: 18.2.0 - react-dom: - specifier: ^18.2.0 - version: 18.2.0(react@18.2.0) - devDependencies: - '@types/node': - specifier: ^20.11.24 - version: 20.11.24 - typescript: - specifier: ^5.3.3 - version: 5.3.3 - -packages: - - '@braintree/sanitize-url@6.0.4': - resolution: {integrity: sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A==} - - '@headlessui/react@1.7.18': - resolution: {integrity: sha512-4i5DOrzwN4qSgNsL4Si61VMkUcWbcSKueUV7sFhpHzQcSShdlHENE5+QBntMSRvHt8NyoFO2AGG8si9lq+w4zQ==} - engines: {node: '>=10'} - peerDependencies: - react: ^16 || ^17 || ^18 - react-dom: ^16 || ^17 || ^18 - - '@mdx-js/mdx@3.0.1': - resolution: {integrity: sha512-eIQ4QTrOWyL3LWEe/bu6Taqzq2HQvHcyTMaOrI95P2/LmJE7AsfPfgJGuFLPVqBUE1BC1rik3VIhU+s9u72arA==} - - '@mdx-js/react@3.0.1': - resolution: {integrity: sha512-9ZrPIU4MGf6et1m1ov3zKf+q9+deetI51zprKB1D/z3NOb+rUxxtEl3mCjW5wTGh6VhRdwPueh1oRzi6ezkA8A==} - peerDependencies: - '@types/react': '>=16' - react: '>=16' - - '@napi-rs/simple-git-android-arm-eabi@0.1.16': - resolution: {integrity: sha512-dbrCL0Pl5KZG7x7tXdtVsA5CO6At5ohDX3myf5xIYn9kN4jDFxsocl8bNt6Vb/hZQoJd8fI+k5VlJt+rFhbdVw==} - engines: {node: '>= 10'} - cpu: [arm] - os: [android] - - '@napi-rs/simple-git-android-arm64@0.1.16': - resolution: {integrity: sha512-xYz+TW5J09iK8SuTAKK2D5MMIsBUXVSs8nYp7HcMi8q6FCRO7yJj96YfP9PvKsc/k64hOyqGmL5DhCzY9Cu1FQ==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [android] - - '@napi-rs/simple-git-darwin-arm64@0.1.16': - resolution: {integrity: sha512-XfgsYqxhUE022MJobeiX563TJqyQyX4FmYCnqrtJwAfivESVeAJiH6bQIum8dDEYMHXCsG7nL8Ok0Dp8k2m42g==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [darwin] - - '@napi-rs/simple-git-darwin-x64@0.1.16': - resolution: {integrity: sha512-tkEVBhD6vgRCbeWsaAQqM3bTfpIVGeitamPPRVSbsq8qgzJ5Dx6ZedH27R7KSsA/uao7mZ3dsrNLXbu1Wy5MzA==} - engines: {node: '>= 10'} - cpu: [x64] - os: [darwin] - - '@napi-rs/simple-git-linux-arm-gnueabihf@0.1.16': - resolution: {integrity: sha512-R6VAyNnp/yRaT7DV1Ao3r67SqTWDa+fNq2LrNy0Z8gXk2wB9ZKlrxFtLPE1WSpWknWtyRDLpRlsorh7Evk7+7w==} - engines: {node: '>= 10'} - cpu: [arm] - os: [linux] - - '@napi-rs/simple-git-linux-arm64-gnu@0.1.16': - resolution: {integrity: sha512-LAGI0opFKw/HBMCV2qIBK3uWSEW9h4xd2ireZKLJy8DBPymX6NrWIamuxYNyCuACnFdPRxR4LaRFy4J5ZwuMdw==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - - '@napi-rs/simple-git-linux-arm64-musl@0.1.16': - resolution: {integrity: sha512-I57Ph0F0Yn2KW93ep+V1EzKhACqX0x49vvSiapqIsdDA2PifdEWLc1LJarBolmK7NKoPqKmf6lAKKO9lhiZzkg==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - - '@napi-rs/simple-git-linux-x64-gnu@0.1.16': - resolution: {integrity: sha512-AZYYFY2V7hlcQASPEOWyOa3e1skzTct9QPzz0LiDM3f/hCFY/wBaU2M6NC5iG3d2Kr38heuyFS/+JqxLm5WaKA==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - - '@napi-rs/simple-git-linux-x64-musl@0.1.16': - resolution: {integrity: sha512-9TyMcYSBJwjT8jwjY9m24BZbu7ozyWTjsmYBYNtK3B0Um1Ov6jthSNneLVvouQ6x+k3Ow+00TiFh6bvmT00r8g==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - - '@napi-rs/simple-git-win32-arm64-msvc@0.1.16': - resolution: {integrity: sha512-uslJ1WuAHCYJWui6xjsyT47SjX6KOHDtClmNO8hqKz1pmDSNY7AjyUY8HxvD1lK9bDnWwc4JYhikS9cxCqHybw==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [win32] - - '@napi-rs/simple-git-win32-x64-msvc@0.1.16': - resolution: {integrity: sha512-SoEaVeCZCDF1MP+M9bMSXsZWgEjk4On9GWADO5JOulvzR1bKjk0s9PMHwe/YztR9F0sJzrCxwtvBZowhSJsQPg==} - engines: {node: '>= 10'} - cpu: [x64] - os: [win32] - - '@napi-rs/simple-git@0.1.16': - resolution: {integrity: sha512-C5wRPw9waqL2jk3jEDeJv+f7ScuO3N0a39HVdyFLkwKxHH4Sya4ZbzZsu2JLi6eEqe7RuHipHL6mC7B2OfYZZw==} - engines: {node: '>= 10'} - - '@next/env@14.1.1': - resolution: {integrity: sha512-7CnQyD5G8shHxQIIg3c7/pSeYFeMhsNbpU/bmvH7ZnDql7mNRgg8O2JZrhrc/soFnfBnKP4/xXNiiSIPn2w8gA==} - - '@next/swc-darwin-arm64@14.1.1': - resolution: {integrity: sha512-yDjSFKQKTIjyT7cFv+DqQfW5jsD+tVxXTckSe1KIouKk75t1qZmj/mV3wzdmFb0XHVGtyRjDMulfVG8uCKemOQ==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [darwin] - - '@next/swc-darwin-x64@14.1.1': - resolution: {integrity: sha512-KCQmBL0CmFmN8D64FHIZVD9I4ugQsDBBEJKiblXGgwn7wBCSe8N4Dx47sdzl4JAg39IkSN5NNrr8AniXLMb3aw==} - engines: {node: '>= 10'} - cpu: [x64] - os: [darwin] - - '@next/swc-linux-arm64-gnu@14.1.1': - resolution: {integrity: sha512-YDQfbWyW0JMKhJf/T4eyFr4b3tceTorQ5w2n7I0mNVTFOvu6CGEzfwT3RSAQGTi/FFMTFcuspPec/7dFHuP7Eg==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - - '@next/swc-linux-arm64-musl@14.1.1': - resolution: {integrity: sha512-fiuN/OG6sNGRN/bRFxRvV5LyzLB8gaL8cbDH5o3mEiVwfcMzyE5T//ilMmaTrnA8HLMS6hoz4cHOu6Qcp9vxgQ==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - - '@next/swc-linux-x64-gnu@14.1.1': - resolution: {integrity: sha512-rv6AAdEXoezjbdfp3ouMuVqeLjE1Bin0AuE6qxE6V9g3Giz5/R3xpocHoAi7CufRR+lnkuUjRBn05SYJ83oKNQ==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - - '@next/swc-linux-x64-musl@14.1.1': - resolution: {integrity: sha512-YAZLGsaNeChSrpz/G7MxO3TIBLaMN8QWMr3X8bt6rCvKovwU7GqQlDu99WdvF33kI8ZahvcdbFsy4jAFzFX7og==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - - '@next/swc-win32-arm64-msvc@14.1.1': - resolution: {integrity: sha512-1L4mUYPBMvVDMZg1inUYyPvFSduot0g73hgfD9CODgbr4xiTYe0VOMTZzaRqYJYBA9mana0x4eaAaypmWo1r5A==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [win32] - - '@next/swc-win32-ia32-msvc@14.1.1': - resolution: {integrity: sha512-jvIE9tsuj9vpbbXlR5YxrghRfMuG0Qm/nZ/1KDHc+y6FpnZ/apsgh+G6t15vefU0zp3WSpTMIdXRUsNl/7RSuw==} - engines: {node: '>= 10'} - cpu: [ia32] - os: [win32] - - '@next/swc-win32-x64-msvc@14.1.1': - resolution: {integrity: sha512-S6K6EHDU5+1KrBDLko7/c1MNy/Ya73pIAmvKeFwsF4RmBFJSO7/7YeD4FnZ4iBdzE69PpQ4sOMU9ORKeNuxe8A==} - engines: {node: '>= 10'} - cpu: [x64] - os: [win32] - - '@popperjs/core@2.11.8': - resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} - - '@shikijs/core@1.6.1': - resolution: {integrity: sha512-CqYyepN4SnBopaoXYwng4NO8riB5ask/LTCkhOFq+GNGtr2X+aKeD767eYdqYukeixEUvv4bXdyTYVaogj7KBw==} - - '@shikijs/twoslash@1.6.1': - resolution: {integrity: sha512-VluGZXQ97sDFyxneOzsPkEHK06A6C1SRDh+kSM9AZAkzHorZaGxF4awgA3rh2K0oZnR94NZzfhq8GtERm38EEQ==} - - '@swc/helpers@0.5.2': - resolution: {integrity: sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==} - - '@tanstack/react-virtual@3.1.3': - resolution: {integrity: sha512-YCzcbF/Ws/uZ0q3Z6fagH+JVhx4JLvbSflgldMgLsuvB8aXjZLLb3HvrEVxY480F9wFlBiXlvQxOyXb5ENPrNA==} - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - - '@tanstack/virtual-core@3.1.3': - resolution: {integrity: sha512-Y5B4EYyv1j9V8LzeAoOVeTg0LI7Fo5InYKgAjkY1Pu9GjtUwX/EKxNcU7ng3sKr99WEf+bPTcktAeybyMOYo+g==} - - '@theguild/remark-mermaid@0.0.5': - resolution: {integrity: sha512-e+ZIyJkEv9jabI4m7q29wZtZv+2iwPGsXJ2d46Zi7e+QcFudiyuqhLhHG/3gX3ZEB+hxTch+fpItyMS8jwbIcw==} - peerDependencies: - react: ^18.2.0 - - '@theguild/remark-npm2yarn@0.3.0': - resolution: {integrity: sha512-Fofw+9airYgjBd9G6PiHHCrptjyUybQ50JH9/5o9LCH54kggJ7stpCofzHjICB8L7VQbQ1Gwu23P/3CMVY1R4Q==} - - '@types/acorn@4.0.6': - resolution: {integrity: sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==} - - '@types/d3-scale-chromatic@3.0.3': - resolution: {integrity: sha512-laXM4+1o5ImZv3RpFAsTRn3TEkzqkytiOY0Dz0sq5cnd1dtNlk6sHLon4OvqaiJb28T0S/TdsBI3Sjsy+keJrw==} - - '@types/d3-scale@4.0.8': - resolution: {integrity: sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==} - - '@types/d3-time@3.0.3': - resolution: {integrity: sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==} - - '@types/debug@4.1.7': - resolution: {integrity: sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==} - - '@types/estree-jsx@1.0.0': - resolution: {integrity: sha512-3qvGd0z8F2ENTGr/GG1yViqfiKmRfrXVx5sJyHGFu3z7m5g5utCQtGp/g29JnjflhtQJBv1WDQukHiT58xPcYQ==} - - '@types/estree@1.0.0': - resolution: {integrity: sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==} - - '@types/hast@3.0.4': - resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} - - '@types/katex@0.16.7': - resolution: {integrity: sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==} - - '@types/mdast@3.0.10': - resolution: {integrity: sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==} - - '@types/mdast@4.0.3': - resolution: {integrity: sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==} - - '@types/mdx@2.0.3': - resolution: {integrity: sha512-IgHxcT3RC8LzFLhKwP3gbMPeaK7BM9eBH46OdapPA7yvuIUJ8H6zHZV53J8hGZcTSnt95jANt+rTBNUUc22ACQ==} - - '@types/ms@0.7.31': - resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==} - - '@types/nlcst@1.0.4': - resolution: {integrity: sha512-ABoYdNQ/kBSsLvZAekMhIPMQ3YUZvavStpKYs7BjLLuKVmIMA0LUgZ7b54zzuWJRbHF80v1cNf4r90Vd6eMQDg==} - - '@types/node@20.11.24': - resolution: {integrity: sha512-Kza43ewS3xoLgCEpQrsT+xRo/EJej1y0kVYGiLFE1NEODXGzTfwiC6tXTLMQskn1X4/Rjlh0MQUvx9W+L9long==} - - '@types/prop-types@15.7.5': - resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} - - '@types/react@18.0.26': - resolution: {integrity: sha512-hCR3PJQsAIXyxhTNSiDFY//LhnMZWpNNr5etoCqx/iUfGc5gXWtQR2Phl908jVR6uPXacojQWTg4qRpkxTuGug==} - - '@types/scheduler@0.16.2': - resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==} - - '@types/unist@2.0.6': - resolution: {integrity: sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==} - - '@types/unist@3.0.2': - resolution: {integrity: sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==} - - '@typescript/vfs@1.5.0': - resolution: {integrity: sha512-AJS307bPgbsZZ9ggCT3wwpg3VbTKMFNHfaY/uF0ahSkYYrPF2dSSKDNIDIQAHm9qJqbLvCsSJH7yN4Vs/CsMMg==} - - '@ungap/structured-clone@1.2.0': - resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} - - acorn-jsx@5.3.2: - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - - acorn@8.8.1: - resolution: {integrity: sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==} - engines: {node: '>=0.4.0'} - hasBin: true - - ansi-styles@3.2.1: - resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} - engines: {node: '>=4'} - - arch@2.2.0: - resolution: {integrity: sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==} - - arg@1.0.0: - resolution: {integrity: sha512-Wk7TEzl1KqvTGs/uyhmHO/3XLd3t1UeU4IstvPXVzGPM522cTjqjNZ99esCkcL52sjqjo8e8CTBcWhkxvGzoAw==} - - argparse@1.0.10: - resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} - - array-iterate@2.0.1: - resolution: {integrity: sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==} - - astring@1.8.3: - resolution: {integrity: sha512-sRpyiNrx2dEYIMmUXprS8nlpRg2Drs8m9ElX9vVEXaCB4XEAJhKfs7IcX0IwShjuOAjLR6wzIrgoptz1n19i1A==} - hasBin: true - - bail@2.0.2: - resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} - - better-react-mathjax@2.0.3: - resolution: {integrity: sha512-wfifT8GFOKb1TWm2+E50I6DJpLZ5kLbch283Lu043EJtwSv0XvZDjr4YfR4d2MjAhqP6SH4VjjrKgbX8R00oCQ==} - peerDependencies: - react: '>=16.8' - - busboy@1.6.0: - resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} - engines: {node: '>=10.16.0'} - - caniuse-lite@1.0.30001591: - resolution: {integrity: sha512-PCzRMei/vXjJyL5mJtzNiUCKP59dm8Apqc3PH8gJkMnMXZGox93RbE76jHsmLwmIo6/3nsYIpJtx0O7u5PqFuQ==} - - ccount@2.0.1: - resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} - - chalk@2.3.0: - resolution: {integrity: sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==} - engines: {node: '>=4'} - - character-entities-html4@2.1.0: - resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} - - character-entities-legacy@3.0.0: - resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} - - character-entities@2.0.2: - resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} - - character-reference-invalid@2.0.1: - resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} - - client-only@0.0.1: - resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} - - clipboardy@1.2.2: - resolution: {integrity: sha512-16KrBOV7bHmHdxcQiCvfUFYVFyEah4FI8vYT1Fr7CGSA4G+xBWMEfUEQJS1hxeHGtI9ju1Bzs9uXSbj5HZKArw==} - engines: {node: '>=4'} - - clsx@2.1.0: - resolution: {integrity: sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==} - engines: {node: '>=6'} - - collapse-white-space@2.1.0: - resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} - - color-convert@1.9.3: - resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} - - color-name@1.1.3: - resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} - - comma-separated-tokens@2.0.3: - resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} - - commander@7.2.0: - resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} - engines: {node: '>= 10'} - - commander@8.3.0: - resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} - engines: {node: '>= 12'} - - commander@9.2.0: - resolution: {integrity: sha512-e2i4wANQiSXgnrBlIatyHtP1odfUp0BbV5Y5nEGbxtIrStkEOAAzCUirvLBNXHLr7kwLvJl6V+4V3XV9x7Wd9w==} - engines: {node: ^12.20.0 || >=14} - - compute-scroll-into-view@3.1.0: - resolution: {integrity: sha512-rj8l8pD4bJ1nx+dAkMhV1xB5RuZEyVysfxJqB1pRchh1KVvwOv9b7CGB8ZfjTImVv2oF+sYMUkMZq6Na5Ftmbg==} - - cose-base@1.0.3: - resolution: {integrity: sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==} - - cross-spawn@5.1.0: - resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==} - - csstype@3.1.1: - resolution: {integrity: sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==} - - cytoscape-cose-bilkent@4.1.0: - resolution: {integrity: sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==} - peerDependencies: - cytoscape: ^3.2.0 - - cytoscape@3.28.1: - resolution: {integrity: sha512-xyItz4O/4zp9/239wCcH8ZcFuuZooEeF8KHRmzjDfGdXsj3OG9MFSMA0pJE0uX3uCN/ygof6hHf4L7lst+JaDg==} - engines: {node: '>=0.10'} - - d3-array@2.12.1: - resolution: {integrity: sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==} - - d3-array@3.2.4: - resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} - engines: {node: '>=12'} - - d3-axis@3.0.0: - resolution: {integrity: sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==} - engines: {node: '>=12'} - - d3-brush@3.0.0: - resolution: {integrity: sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==} - engines: {node: '>=12'} - - d3-chord@3.0.1: - resolution: {integrity: sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==} - engines: {node: '>=12'} - - d3-color@3.1.0: - resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==} - engines: {node: '>=12'} - - d3-contour@4.0.2: - resolution: {integrity: sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==} - engines: {node: '>=12'} - - d3-delaunay@6.0.4: - resolution: {integrity: sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==} - engines: {node: '>=12'} - - d3-dispatch@3.0.1: - resolution: {integrity: sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==} - engines: {node: '>=12'} - - d3-drag@3.0.0: - resolution: {integrity: sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==} - engines: {node: '>=12'} - - d3-dsv@3.0.1: - resolution: {integrity: sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==} - engines: {node: '>=12'} - hasBin: true - - d3-ease@3.0.1: - resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==} - engines: {node: '>=12'} - - d3-fetch@3.0.1: - resolution: {integrity: sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==} - engines: {node: '>=12'} - - d3-force@3.0.0: - resolution: {integrity: sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==} - engines: {node: '>=12'} - - d3-format@3.1.0: - resolution: {integrity: sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==} - engines: {node: '>=12'} - - d3-geo@3.1.0: - resolution: {integrity: sha512-JEo5HxXDdDYXCaWdwLRt79y7giK8SbhZJbFWXqbRTolCHFI5jRqteLzCsq51NKbUoX0PjBVSohxrx+NoOUujYA==} - engines: {node: '>=12'} - - d3-hierarchy@3.1.2: - resolution: {integrity: sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==} - engines: {node: '>=12'} - - d3-interpolate@3.0.1: - resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} - engines: {node: '>=12'} - - d3-path@1.0.9: - resolution: {integrity: sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==} - - d3-path@3.1.0: - resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==} - engines: {node: '>=12'} - - d3-polygon@3.0.1: - resolution: {integrity: sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==} - engines: {node: '>=12'} - - d3-quadtree@3.0.1: - resolution: {integrity: sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==} - engines: {node: '>=12'} - - d3-random@3.0.1: - resolution: {integrity: sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==} - engines: {node: '>=12'} - - d3-sankey@0.12.3: - resolution: {integrity: sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==} - - d3-scale-chromatic@3.0.0: - resolution: {integrity: sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g==} - engines: {node: '>=12'} - - d3-scale@4.0.2: - resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==} - engines: {node: '>=12'} - - d3-selection@3.0.0: - resolution: {integrity: sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==} - engines: {node: '>=12'} - - d3-shape@1.3.7: - resolution: {integrity: sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==} - - d3-shape@3.2.0: - resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==} - engines: {node: '>=12'} - - d3-time-format@4.1.0: - resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==} - engines: {node: '>=12'} - - d3-time@3.1.0: - resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==} - engines: {node: '>=12'} - - d3-timer@3.0.1: - resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==} - engines: {node: '>=12'} - - d3-transition@3.0.1: - resolution: {integrity: sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==} - engines: {node: '>=12'} - peerDependencies: - d3-selection: 2 - 3 - - d3-zoom@3.0.0: - resolution: {integrity: sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==} - engines: {node: '>=12'} - - d3@7.8.5: - resolution: {integrity: sha512-JgoahDG51ncUfJu6wX/1vWQEqOflgXyl4MaHqlcSruTez7yhaRKR9i8VjjcQGeS2en/jnFivXuaIMnseMMt0XA==} - engines: {node: '>=12'} - - dagre-d3-es@7.0.10: - resolution: {integrity: sha512-qTCQmEhcynucuaZgY5/+ti3X/rnszKZhEQH/ZdWdtP1tA/y3VoHJzcVrO9pjjJCNpigfscAtoUB5ONcd2wNn0A==} - - dayjs@1.11.10: - resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==} - - debug@4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - decode-named-character-reference@1.0.2: - resolution: {integrity: sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==} - - delaunator@5.0.1: - resolution: {integrity: sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==} - - dequal@2.0.3: - resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} - engines: {node: '>=6'} - - devlop@1.1.0: - resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} - - diff@5.1.0: - resolution: {integrity: sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==} - engines: {node: '>=0.3.1'} - - dompurify@3.0.9: - resolution: {integrity: sha512-uyb4NDIvQ3hRn6NiC+SIFaP4mJ/MdXlvtunaqK9Bn6dD3RuB/1S/gasEjDHD8eiaqdSael2vBv+hOs7Y+jhYOQ==} - - elkjs@0.9.2: - resolution: {integrity: sha512-2Y/RaA1pdgSHpY0YG4TYuYCD2wh97CRvu22eLG3Kz0pgQ/6KbIFTxsTnDc4MH/6hFlg2L/9qXrDMG0nMjP63iw==} - - entities@4.5.0: - resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} - engines: {node: '>=0.12'} - - escape-string-regexp@1.0.5: - resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} - engines: {node: '>=0.8.0'} - - escape-string-regexp@5.0.0: - resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} - engines: {node: '>=12'} - - esm@3.2.25: - resolution: {integrity: sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==} - engines: {node: '>=6'} - - esprima@4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} - hasBin: true - - estree-util-attach-comments@3.0.0: - resolution: {integrity: sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==} - - estree-util-build-jsx@3.0.1: - resolution: {integrity: sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==} - - estree-util-is-identifier-name@2.0.1: - resolution: {integrity: sha512-rxZj1GkQhY4x1j/CSnybK9cGuMFQYFPLq0iNyopqf14aOVLFtMv7Esika+ObJWPWiOHuMOAHz3YkWoLYYRnzWQ==} - - estree-util-is-identifier-name@3.0.0: - resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} - - estree-util-to-js@2.0.0: - resolution: {integrity: sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==} - - estree-util-value-to-estree@1.3.0: - resolution: {integrity: sha512-Y+ughcF9jSUJvncXwqRageavjrNPAI+1M/L3BI3PyLp1nmgYTGUXU6t5z1Y7OWuThoDdhPME07bQU+d5LxdJqw==} - engines: {node: '>=12.0.0'} - - estree-util-value-to-estree@3.1.1: - resolution: {integrity: sha512-5mvUrF2suuv5f5cGDnDphIy4/gW86z82kl5qG6mM9z04SEQI4FB5Apmaw/TGEf3l55nLtMs5s51dmhUzvAHQCA==} - - estree-util-visit@2.0.0: - resolution: {integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==} - - estree-walker@3.0.1: - resolution: {integrity: sha512-woY0RUD87WzMBUiZLx8NsYr23N5BKsOMZHhu2hoNRVh6NXGfoiT1KOL8G3UHlJAnEDGmfa5ubNA/AacfG+Kb0g==} - - execa@0.8.0: - resolution: {integrity: sha512-zDWS+Rb1E8BlqqhALSt9kUhss8Qq4nN3iof3gsOdyINksElaPyNBtKUMTR62qhvgVWR0CqCX7sdnKe4MnUbFEA==} - engines: {node: '>=4'} - - extend-shallow@2.0.1: - resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} - engines: {node: '>=0.10.0'} - - extend@3.0.2: - resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} - - fault@2.0.1: - resolution: {integrity: sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==} - - flexsearch@0.7.43: - resolution: {integrity: sha512-c5o/+Um8aqCSOXGcZoqZOm+NqtVwNsvVpWv6lfmSclU954O3wvQKxxK8zj74fPaSJbXpSLTs4PRhh+wnoCXnKg==} - - focus-visible@5.2.0: - resolution: {integrity: sha512-Rwix9pBtC1Nuy5wysTmKy+UjbDJpIfg8eHjw0rjZ1mX4GNLz1Bmd16uDpI3Gk1i70Fgcs8Csg2lPm8HULFg9DQ==} - - format@0.2.2: - resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==} - engines: {node: '>=0.4.x'} - - get-stream@3.0.0: - resolution: {integrity: sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==} - engines: {node: '>=4'} - - github-slugger@2.0.0: - resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==} - - graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - - gray-matter@4.0.3: - resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==} - engines: {node: '>=6.0'} - - has-flag@2.0.0: - resolution: {integrity: sha512-P+1n3MnwjR/Epg9BBo1KT8qbye2g2Ou4sFumihwt6I4tsUX7jnLcX4BTOSKg/B1ZrIYMN9FcEnG4x5a7NB8Eng==} - engines: {node: '>=0.10.0'} - - hast-util-from-dom@5.0.0: - resolution: {integrity: sha512-d6235voAp/XR3Hh5uy7aGLbM3S4KamdW0WEgOaU1YoewnuYw4HXb5eRtv9g65m/RFGEfUY1Mw4UqCc5Y8L4Stg==} - - hast-util-from-html-isomorphic@2.0.0: - resolution: {integrity: sha512-zJfpXq44yff2hmE0XmwEOzdWin5xwH+QIhMLOScpX91e/NSGPsAzNCvLQDIEPyO2TXi+lBmU6hjLIhV8MwP2kw==} - - hast-util-from-html@2.0.1: - resolution: {integrity: sha512-RXQBLMl9kjKVNkJTIO6bZyb2n+cUH8LFaSSzo82jiLT6Tfc+Pt7VQCS+/h3YwG4jaNE2TA2sdJisGWR+aJrp0g==} - - hast-util-from-parse5@8.0.1: - resolution: {integrity: sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ==} - - hast-util-is-element@3.0.0: - resolution: {integrity: sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==} - - hast-util-parse-selector@4.0.0: - resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==} - - hast-util-raw@9.0.2: - resolution: {integrity: sha512-PldBy71wO9Uq1kyaMch9AHIghtQvIwxBUkv823pKmkTM3oV1JxtsTNYdevMxvUHqcnOAuO65JKU2+0NOxc2ksA==} - - hast-util-to-estree@3.1.0: - resolution: {integrity: sha512-lfX5g6hqVh9kjS/B9E2gSkvHH4SZNiQFiqWS0x9fENzEl+8W12RqdRxX6d/Cwxi30tPQs3bIO+aolQJNp1bIyw==} - - hast-util-to-jsx-runtime@2.3.0: - resolution: {integrity: sha512-H/y0+IWPdsLLS738P8tDnrQ8Z+dj12zQQ6WC11TIM21C8WFVoIxcqWXf2H3hiTVZjF1AWqoimGwrTWecWrnmRQ==} - - hast-util-to-parse5@8.0.0: - resolution: {integrity: sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==} - - hast-util-to-string@3.0.0: - resolution: {integrity: sha512-OGkAxX1Ua3cbcW6EJ5pT/tslVb90uViVkcJ4ZZIMW/R33DX/AkcJcRrPebPwJkHYwlDHXz4aIwvAAaAdtrACFA==} - - hast-util-to-text@4.0.0: - resolution: {integrity: sha512-EWiE1FSArNBPUo1cKWtzqgnuRQwEeQbQtnFJRYV1hb1BWDgrAlBU0ExptvZMM/KSA82cDpm2sFGf3Dmc5Mza3w==} - - hast-util-whitespace@3.0.0: - resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} - - hastscript@8.0.0: - resolution: {integrity: sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==} - - heap@0.2.7: - resolution: {integrity: sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==} - - html-void-elements@3.0.0: - resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} - - iconv-lite@0.6.3: - resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} - engines: {node: '>=0.10.0'} - - inline-style-parser@0.1.1: - resolution: {integrity: sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==} - - inline-style-parser@0.2.3: - resolution: {integrity: sha512-qlD8YNDqyTKTyuITrDOffsl6Tdhv+UC4hcdAVuQsK4IMQ99nSgd1MIA/Q+jQYoh9r3hVUXhYh7urSRmXPkW04g==} - - internmap@1.0.1: - resolution: {integrity: sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==} - - internmap@2.0.3: - resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} - engines: {node: '>=12'} - - intersection-observer@0.12.2: - resolution: {integrity: sha512-7m1vEcPCxXYI8HqnL8CKI6siDyD+eIWSwgB3DZA+ZTogxk9I4CDnj4wilt9x/+/QbHI4YG5YZNmC6458/e9Ktg==} - - is-alphabetical@2.0.1: - resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} - - is-alphanumerical@2.0.1: - resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} - - is-buffer@2.0.5: - resolution: {integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==} - engines: {node: '>=4'} - - is-decimal@2.0.1: - resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} - - is-extendable@0.1.1: - resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} - engines: {node: '>=0.10.0'} - - is-hexadecimal@2.0.1: - resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} - - is-plain-obj@3.0.0: - resolution: {integrity: sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==} - engines: {node: '>=10'} - - is-plain-obj@4.1.0: - resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} - engines: {node: '>=12'} - - is-reference@3.0.0: - resolution: {integrity: sha512-Eo1W3wUoHWoCoVM4GVl/a+K0IgiqE5aIo4kJABFyMum1ZORlPkC+UC357sSQUL5w5QCE5kCC9upl75b7+7CY/Q==} - - is-stream@1.1.0: - resolution: {integrity: sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==} - engines: {node: '>=0.10.0'} - - isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - - js-tokens@4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - - js-yaml@3.14.1: - resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} - hasBin: true - - katex@0.16.9: - resolution: {integrity: sha512-fsSYjWS0EEOwvy81j3vRA8TEAhQhKiqO+FQaKWp0m39qwOzHVBgAUBIXWj1pB+O2W3fIpNa6Y9KSKCVbfPhyAQ==} - hasBin: true - - khroma@2.1.0: - resolution: {integrity: sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==} - - kind-of@6.0.3: - resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} - engines: {node: '>=0.10.0'} - - kleur@4.1.5: - resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} - engines: {node: '>=6'} - - layout-base@1.0.2: - resolution: {integrity: sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==} - - lodash-es@4.17.21: - resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} - - lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - - longest-streak@3.1.0: - resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} - - loose-envify@1.4.0: - resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} - hasBin: true - - lru-cache@4.1.5: - resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==} - - markdown-extensions@2.0.0: - resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==} - engines: {node: '>=16'} - - markdown-table@3.0.3: - resolution: {integrity: sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==} - - mathjax-full@3.2.2: - resolution: {integrity: sha512-+LfG9Fik+OuI8SLwsiR02IVdjcnRCy5MufYLi0C3TdMT56L/pjB0alMVGgoWJF8pN9Rc7FESycZB9BMNWIid5w==} - - mdast-util-find-and-replace@3.0.1: - resolution: {integrity: sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==} - - mdast-util-from-markdown@1.3.1: - resolution: {integrity: sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==} - - mdast-util-from-markdown@2.0.1: - resolution: {integrity: sha512-aJEUyzZ6TzlsX2s5B4Of7lN7EQtAxvtradMMglCQDyaTFgse6CmtmdJ15ElnVRlCg1vpNyVtbem0PWzlNieZsA==} - - mdast-util-frontmatter@2.0.1: - resolution: {integrity: sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==} - - mdast-util-gfm-autolink-literal@2.0.0: - resolution: {integrity: sha512-FyzMsduZZHSc3i0Px3PQcBT4WJY/X/RCtEJKuybiC6sjPqLv7h1yqAkmILZtuxMSsUyaLUWNp71+vQH2zqp5cg==} - - mdast-util-gfm-footnote@2.0.0: - resolution: {integrity: sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==} - - mdast-util-gfm-strikethrough@2.0.0: - resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} - - mdast-util-gfm-table@2.0.0: - resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} - - mdast-util-gfm-task-list-item@2.0.0: - resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} - - mdast-util-gfm@3.0.0: - resolution: {integrity: sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==} - - mdast-util-math@3.0.0: - resolution: {integrity: sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w==} - - mdast-util-mdx-expression@2.0.0: - resolution: {integrity: sha512-fGCu8eWdKUKNu5mohVGkhBXCXGnOTLuFqOvGMvdikr+J1w7lDJgxThOKpwRWzzbyXAU2hhSwsmssOY4yTokluw==} - - mdast-util-mdx-jsx@3.1.2: - resolution: {integrity: sha512-eKMQDeywY2wlHc97k5eD8VC+9ASMjN8ItEZQNGwJ6E0XWKiW/Z0V5/H8pvoXUf+y+Mj0VIgeRRbujBmFn4FTyA==} - - mdast-util-mdx@3.0.0: - resolution: {integrity: sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==} - - mdast-util-mdxjs-esm@2.0.1: - resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==} - - mdast-util-phrasing@4.1.0: - resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} - - mdast-util-to-hast@13.1.0: - resolution: {integrity: sha512-/e2l/6+OdGp/FB+ctrJ9Avz71AN/GRH3oi/3KAx/kMnoUsD6q0woXlDT8lLEeViVKE7oZxE7RXzvO3T8kF2/sA==} - - mdast-util-to-markdown@2.1.0: - resolution: {integrity: sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==} - - mdast-util-to-string@3.1.0: - resolution: {integrity: sha512-n4Vypz/DZgwo0iMHLQL49dJzlp7YtAJP+N07MZHpjPf/5XJuHUWstviF4Mn2jEiR/GNmtnRRqnwsXExk3igfFA==} - - mdast-util-to-string@4.0.0: - resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} - - mermaid@10.8.0: - resolution: {integrity: sha512-9CzfSreRjdDJxX796+jW4zjEq0DVw5xVF0nWsqff8OTbrt+ml0TZ5PyYUjjUZJa2NYxYJZZXewEquxGiM8qZEA==} - - mhchemparser@4.2.1: - resolution: {integrity: sha512-kYmyrCirqJf3zZ9t/0wGgRZ4/ZJw//VwaRVGA75C4nhE60vtnIzhl9J9ndkX/h6hxSN7pjg/cE0VxbnNM+bnDQ==} - - micromark-core-commonmark@1.0.6: - resolution: {integrity: sha512-K+PkJTxqjFfSNkfAhp4GB+cZPfQd6dxtTXnf+RjZOV7T4EEXnvgzOcnp+eSTmpGk9d1S9sL6/lqrgSNn/s0HZA==} - - micromark-core-commonmark@2.0.1: - resolution: {integrity: sha512-CUQyKr1e///ZODyD1U3xit6zXwy1a8q2a1S1HKtIlmgvurrEpaw/Y9y6KSIbF8P59cn/NjzHyO+Q2fAyYLQrAA==} - - micromark-extension-frontmatter@2.0.0: - resolution: {integrity: sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==} - - micromark-extension-gfm-autolink-literal@2.0.0: - resolution: {integrity: sha512-rTHfnpt/Q7dEAK1Y5ii0W8bhfJlVJFnJMHIPisfPK3gpVNuOP0VnRl96+YJ3RYWV/P4gFeQoGKNlT3RhuvpqAg==} - - micromark-extension-gfm-footnote@2.0.0: - resolution: {integrity: sha512-6Rzu0CYRKDv3BfLAUnZsSlzx3ak6HAoI85KTiijuKIz5UxZxbUI+pD6oHgw+6UtQuiRwnGRhzMmPRv4smcz0fg==} - - micromark-extension-gfm-strikethrough@2.0.0: - resolution: {integrity: sha512-c3BR1ClMp5fxxmwP6AoOY2fXO9U8uFMKs4ADD66ahLTNcwzSCyRVU4k7LPV5Nxo/VJiR4TdzxRQY2v3qIUceCw==} - - micromark-extension-gfm-table@2.0.0: - resolution: {integrity: sha512-PoHlhypg1ItIucOaHmKE8fbin3vTLpDOUg8KAr8gRCF1MOZI9Nquq2i/44wFvviM4WuxJzc3demT8Y3dkfvYrw==} - - micromark-extension-gfm-tagfilter@2.0.0: - resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} - - micromark-extension-gfm-task-list-item@2.0.1: - resolution: {integrity: sha512-cY5PzGcnULaN5O7T+cOzfMoHjBW7j+T9D2sucA5d/KbsBTPcYdebm9zUd9zzdgJGCwahV+/W78Z3nbulBYVbTw==} - - micromark-extension-gfm@3.0.0: - resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} - - micromark-extension-math@3.0.0: - resolution: {integrity: sha512-iJ2Q28vBoEovLN5o3GO12CpqorQRYDPT+p4zW50tGwTfJB+iv/VnB6Ini+gqa24K97DwptMBBIvVX6Bjk49oyQ==} - - micromark-extension-mdx-expression@3.0.0: - resolution: {integrity: sha512-sI0nwhUDz97xyzqJAbHQhp5TfaxEvZZZ2JDqUo+7NvyIYG6BZ5CPPqj2ogUoPJlmXHBnyZUzISg9+oUmU6tUjQ==} - - micromark-extension-mdx-jsx@3.0.0: - resolution: {integrity: sha512-uvhhss8OGuzR4/N17L1JwvmJIpPhAd8oByMawEKx6NVdBCbesjH4t+vjEp3ZXft9DwvlKSD07fCeI44/N0Vf2w==} - - micromark-extension-mdx-md@2.0.0: - resolution: {integrity: sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==} - - micromark-extension-mdxjs-esm@3.0.0: - resolution: {integrity: sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==} - - micromark-extension-mdxjs@3.0.0: - resolution: {integrity: sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==} - - micromark-factory-destination@1.0.0: - resolution: {integrity: sha512-eUBA7Rs1/xtTVun9TmV3gjfPz2wEwgK5R5xcbIM5ZYAtvGF6JkyaDsj0agx8urXnO31tEO6Ug83iVH3tdedLnw==} - - micromark-factory-destination@2.0.0: - resolution: {integrity: sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==} - - micromark-factory-label@1.0.2: - resolution: {integrity: sha512-CTIwxlOnU7dEshXDQ+dsr2n+yxpP0+fn271pu0bwDIS8uqfFcumXpj5mLn3hSC8iw2MUr6Gx8EcKng1dD7i6hg==} - - micromark-factory-label@2.0.0: - resolution: {integrity: sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==} - - micromark-factory-mdx-expression@2.0.1: - resolution: {integrity: sha512-F0ccWIUHRLRrYp5TC9ZYXmZo+p2AM13ggbsW4T0b5CRKP8KHVRB8t4pwtBgTxtjRmwrK0Irwm7vs2JOZabHZfg==} - - micromark-factory-space@1.0.0: - resolution: {integrity: sha512-qUmqs4kj9a5yBnk3JMLyjtWYN6Mzfcx8uJfi5XAveBniDevmZasdGBba5b4QsvRcAkmvGo5ACmSUmyGiKTLZew==} - - micromark-factory-space@2.0.0: - resolution: {integrity: sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==} - - micromark-factory-title@1.0.2: - resolution: {integrity: sha512-zily+Nr4yFqgMGRKLpTVsNl5L4PMu485fGFDOQJQBl2NFpjGte1e86zC0da93wf97jrc4+2G2GQudFMHn3IX+A==} - - micromark-factory-title@2.0.0: - resolution: {integrity: sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==} - - micromark-factory-whitespace@1.0.0: - resolution: {integrity: sha512-Qx7uEyahU1lt1RnsECBiuEbfr9INjQTGa6Err+gF3g0Tx4YEviPbqqGKNv/NrBaE7dVHdn1bVZKM/n5I/Bak7A==} - - micromark-factory-whitespace@2.0.0: - resolution: {integrity: sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==} - - micromark-util-character@1.1.0: - resolution: {integrity: sha512-agJ5B3unGNJ9rJvADMJ5ZiYjBRyDpzKAOk01Kpi1TKhlT1APx3XZk6eN7RtSz1erbWHC2L8T3xLZ81wdtGRZzg==} - - micromark-util-character@2.1.0: - resolution: {integrity: sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==} - - micromark-util-chunked@1.0.0: - resolution: {integrity: sha512-5e8xTis5tEZKgesfbQMKRCyzvffRRUX+lK/y+DvsMFdabAicPkkZV6gO+FEWi9RfuKKoxxPwNL+dFF0SMImc1g==} - - micromark-util-chunked@2.0.0: - resolution: {integrity: sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==} - - micromark-util-classify-character@1.0.0: - resolution: {integrity: sha512-F8oW2KKrQRb3vS5ud5HIqBVkCqQi224Nm55o5wYLzY/9PwHGXC01tr3d7+TqHHz6zrKQ72Okwtvm/xQm6OVNZA==} - - micromark-util-classify-character@2.0.0: - resolution: {integrity: sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==} - - micromark-util-combine-extensions@1.0.0: - resolution: {integrity: sha512-J8H058vFBdo/6+AsjHp2NF7AJ02SZtWaVUjsayNFeAiydTxUwViQPxN0Hf8dp4FmCQi0UUFovFsEyRSUmFH3MA==} - - micromark-util-combine-extensions@2.0.0: - resolution: {integrity: sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==} - - micromark-util-decode-numeric-character-reference@1.0.0: - resolution: {integrity: sha512-OzO9AI5VUtrTD7KSdagf4MWgHMtET17Ua1fIpXTpuhclCqD8egFWo85GxSGvxgkGS74bEahvtM0WP0HjvV0e4w==} - - micromark-util-decode-numeric-character-reference@2.0.1: - resolution: {integrity: sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==} - - micromark-util-decode-string@1.0.2: - resolution: {integrity: sha512-DLT5Ho02qr6QWVNYbRZ3RYOSSWWFuH3tJexd3dgN1odEuPNxCngTCXJum7+ViRAd9BbdxCvMToPOD/IvVhzG6Q==} - - micromark-util-decode-string@2.0.0: - resolution: {integrity: sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==} - - micromark-util-encode@1.0.1: - resolution: {integrity: sha512-U2s5YdnAYexjKDel31SVMPbfi+eF8y1U4pfiRW/Y8EFVCy/vgxk/2wWTxzcqE71LHtCuCzlBDRU2a5CQ5j+mQA==} - - micromark-util-encode@2.0.0: - resolution: {integrity: sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==} - - micromark-util-events-to-acorn@2.0.2: - resolution: {integrity: sha512-Fk+xmBrOv9QZnEDguL9OI9/NQQp6Hz4FuQ4YmCb/5V7+9eAh1s6AYSvL20kHkD67YIg7EpE54TiSlcsf3vyZgA==} - - micromark-util-html-tag-name@1.1.0: - resolution: {integrity: sha512-BKlClMmYROy9UiV03SwNmckkjn8QHVaWkqoAqzivabvdGcwNGMMMH/5szAnywmsTBUzDsU57/mFi0sp4BQO6dA==} - - micromark-util-html-tag-name@2.0.0: - resolution: {integrity: sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==} - - micromark-util-normalize-identifier@1.0.0: - resolution: {integrity: sha512-yg+zrL14bBTFrQ7n35CmByWUTFsgst5JhA4gJYoty4Dqzj4Z4Fr/DHekSS5aLfH9bdlfnSvKAWsAgJhIbogyBg==} - - micromark-util-normalize-identifier@2.0.0: - resolution: {integrity: sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==} - - micromark-util-resolve-all@1.0.0: - resolution: {integrity: sha512-CB/AGk98u50k42kvgaMM94wzBqozSzDDaonKU7P7jwQIuH2RU0TeBqGYJz2WY1UdihhjweivStrJ2JdkdEmcfw==} - - micromark-util-resolve-all@2.0.0: - resolution: {integrity: sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==} - - micromark-util-sanitize-uri@1.1.0: - resolution: {integrity: sha512-RoxtuSCX6sUNtxhbmsEFQfWzs8VN7cTctmBPvYivo98xb/kDEoTCtJQX5wyzIYEmk/lvNFTat4hL8oW0KndFpg==} - - micromark-util-sanitize-uri@2.0.0: - resolution: {integrity: sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==} - - micromark-util-subtokenize@1.0.2: - resolution: {integrity: sha512-d90uqCnXp/cy4G881Ub4psE57Sf8YD0pim9QdjCRNjfas2M1u6Lbt+XZK9gnHL2XFhnozZiEdCa9CNfXSfQ6xA==} - - micromark-util-subtokenize@2.0.1: - resolution: {integrity: sha512-jZNtiFl/1aY73yS3UGQkutD0UbhTt68qnRpw2Pifmz5wV9h8gOVsN70v+Lq/f1rKaU/W8pxRe8y8Q9FX1AOe1Q==} - - micromark-util-symbol@1.0.1: - resolution: {integrity: sha512-oKDEMK2u5qqAptasDAwWDXq0tG9AssVwAx3E9bBF3t/shRIGsWIRG+cGafs2p/SnDSOecnt6hZPCE2o6lHfFmQ==} - - micromark-util-symbol@2.0.0: - resolution: {integrity: sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==} - - micromark-util-types@1.0.2: - resolution: {integrity: sha512-DCfg/T8fcrhrRKTPjRrw/5LLvdGV7BHySf/1LOZx7TzWZdYRjogNtyNq885z3nNallwr3QUKARjqvHqX1/7t+w==} - - micromark-util-types@2.0.0: - resolution: {integrity: sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==} - - micromark@3.1.0: - resolution: {integrity: sha512-6Mj0yHLdUZjHnOPgr5xfWIMqMWS12zDN6iws9SLuSz76W8jTtAv24MN4/CL7gJrl5vtxGInkkqDv/JIoRsQOvA==} - - micromark@4.0.0: - resolution: {integrity: sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==} - - mj-context-menu@0.6.1: - resolution: {integrity: sha512-7NO5s6n10TIV96d4g2uDpG7ZDpIhMh0QNfGdJw/W47JswFcosz457wqz/b5sAKvl12sxINGFCn80NZHKwxQEXA==} - - mri@1.2.0: - resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} - engines: {node: '>=4'} - - ms@2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - - nanoid@3.3.7: - resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - - next-themes@0.3.0: - resolution: {integrity: sha512-/QHIrsYpd6Kfk7xakK4svpDI5mmXP0gfvCoJdGpZQ2TOrQZmsW0QxjaiLn8wbIKjtm4BTSqLoix4lxYYOnLJ/w==} - peerDependencies: - react: ^16.8 || ^17 || ^18 - react-dom: ^16.8 || ^17 || ^18 - - next@14.1.1: - resolution: {integrity: sha512-McrGJqlGSHeaz2yTRPkEucxQKe5Zq7uPwyeHNmJaZNY4wx9E9QdxmTp310agFRoMuIYgQrCrT3petg13fSVOww==} - engines: {node: '>=18.17.0'} - hasBin: true - peerDependencies: - '@opentelemetry/api': ^1.1.0 - react: ^18.2.0 - react-dom: ^18.2.0 - sass: ^1.3.0 - peerDependenciesMeta: - '@opentelemetry/api': - optional: true - sass: - optional: true - - nextra-theme-docs@3.0.0-alpha.24: - resolution: {integrity: sha512-AUuv3o1xYzGGvUP/lxxf7i++Zyycy4bH22l6T8uDVez2n0j/RDbzqmSIdL4Jh4POUd0fyxEG+BUomKXKyj3L1g==} - peerDependencies: - next: '>=13' - nextra: 3.0.0-alpha.24 - react: '>=16.13.1' - react-dom: '>=16.13.1' - - nextra@3.0.0-alpha.24: - resolution: {integrity: sha512-KScl/DQG68JBGy6gfOFNdVcrlc24YvcegGnYwUXvpCoHx2YcBUSp6FE7LeaX/C/mI4PPIMmTJuEWIjGH9DXeCQ==} - engines: {node: '>=18'} - peerDependencies: - next: '>=13' - react: '>=16.13.1' - react-dom: '>=16.13.1' - - nlcst-to-string@3.1.1: - resolution: {integrity: sha512-63mVyqaqt0cmn2VcI2aH6kxe1rLAmSROqHMA0i4qqg1tidkfExgpb0FGMikMCn86mw5dFtBtEANfmSSK7TjNHw==} - - non-layered-tidy-tree-layout@2.0.2: - resolution: {integrity: sha512-gkXMxRzUH+PB0ax9dUN0yYF0S25BqeAYqhgMaLUFmpXLEk7Fcu8f4emJuOAY0V8kjDICxROIKsTAKsV/v355xw==} - - npm-run-path@2.0.2: - resolution: {integrity: sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==} - engines: {node: '>=4'} - - npm-to-yarn@2.2.1: - resolution: {integrity: sha512-O/j/ROyX0KGLG7O6Ieut/seQ0oiTpHF2tXAcFbpdTLQFiaNtkyTXXocM1fwpaa60dg1qpWj0nHlbNhx6qwuENQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - p-finally@1.0.0: - resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} - engines: {node: '>=4'} - - p-limit@4.0.0: - resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - parse-entities@4.0.0: - resolution: {integrity: sha512-5nk9Fn03x3rEhGaX1FU6IDwG/k+GxLXlFAkgrbM1asuAFl3BhdQWvASaIsmwWypRNcZKHPYnIuOSfIWEyEQnPQ==} - - parse-latin@5.0.1: - resolution: {integrity: sha512-b/K8ExXaWC9t34kKeDV8kGXBkXZ1HCSAZRYE7HR14eA1GlXX5L8iWhs8USJNhQU9q5ci413jCKF0gOyovvyRBg==} - - parse-numeric-range@1.3.0: - resolution: {integrity: sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==} - - parse5@7.1.2: - resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==} - - path-key@2.0.1: - resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} - engines: {node: '>=4'} - - periscopic@3.0.4: - resolution: {integrity: sha512-SFx68DxCv0Iyo6APZuw/AKewkkThGwssmU0QWtTlvov3VAtPX+QJ4CadwSaz8nrT5jPIuxdvJWB4PnD2KNDxQg==} - - picocolors@1.0.0: - resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} - - postcss@8.4.31: - resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} - engines: {node: ^10 || ^12 || >=14} - - property-information@6.2.0: - resolution: {integrity: sha512-kma4U7AFCTwpqq5twzC1YVIDXSqg6qQK6JN0smOw8fgRy1OkMi0CYSzFmsy6dnqSenamAtj0CyXMUJ1Mf6oROg==} - - pseudomap@1.0.2: - resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==} - - react-dom@18.2.0: - resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} - peerDependencies: - react: ^18.2.0 - - react@18.2.0: - resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} - engines: {node: '>=0.10.0'} - - reading-time@1.5.0: - resolution: {integrity: sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg==} - - rehype-katex@7.0.0: - resolution: {integrity: sha512-h8FPkGE00r2XKU+/acgqwWUlyzve1IiOKwsEkg4pDL3k48PiE0Pt+/uLtVHDVkN1yA4iurZN6UES8ivHVEQV6Q==} - - rehype-parse@9.0.0: - resolution: {integrity: sha512-WG7nfvmWWkCR++KEkZevZb/uw41E8TsH4DsY9UxsTbIXCVGbAs4S+r8FrQ+OtH5EEQAs+5UxKC42VinkmpA1Yw==} - - rehype-pretty-code@0.13.0: - resolution: {integrity: sha512-+22dz1StXlF7dlMyOySNaVxgcGhMI4BCxq0JxJJPWYGiKsI6cu5jyuIKGHXHvH18D8sv1rdKtvsY9UEfN3++SQ==} - engines: {node: '>=18'} - peerDependencies: - shiki: ^1.0.0 - - rehype-raw@7.0.0: - resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==} - - remark-frontmatter@5.0.0: - resolution: {integrity: sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ==} - - remark-gfm@4.0.0: - resolution: {integrity: sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA==} - - remark-math@6.0.0: - resolution: {integrity: sha512-MMqgnP74Igy+S3WwnhQ7kqGlEerTETXMvJhrUzDikVZ2/uogJCb+WHUg97hK9/jcfc0dkD73s3LN8zU49cTEtA==} - - remark-mdx@3.0.1: - resolution: {integrity: sha512-3Pz3yPQ5Rht2pM5R+0J2MrGoBSrzf+tJG94N+t/ilfdh8YLyyKYtidAYwTveB20BoHAcwIopOUqhcmh2F7hGYA==} - - remark-parse@11.0.0: - resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} - - remark-reading-time@2.0.1: - resolution: {integrity: sha512-fy4BKy9SRhtYbEHvp6AItbRTnrhiDGbqLQTSYVbQPGuRCncU1ubSsh9p/W5QZSxtYcUXv8KGL0xBgPLyNJA1xw==} - - remark-rehype@11.1.0: - resolution: {integrity: sha512-z3tJrAs2kIs1AqIIy6pzHmAHlF1hWQ+OdY4/hv+Wxe35EhyLKcajL33iUEn3ScxtFox9nUvRufR/Zre8Q08H/g==} - - remark-smartypants@2.1.0: - resolution: {integrity: sha512-qoF6Vz3BjU2tP6OfZqHOvCU0ACmu/6jhGaINSQRI9mM7wCxNQTKB3JUAN4SVoN2ybElEDTxBIABRep7e569iJw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - remark-stringify@11.0.0: - resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} - - retext-latin@3.1.0: - resolution: {integrity: sha512-5MrD1tuebzO8ppsja5eEu+ZbBeUNCjoEarn70tkXOS7Bdsdf6tNahsv2bY0Z8VooFF6cw7/6S+d3yI/TMlMVVQ==} - - retext-smartypants@5.2.0: - resolution: {integrity: sha512-Do8oM+SsjrbzT2UNIKgheP0hgUQTDDQYyZaIY3kfq0pdFzoPk+ZClYJ+OERNXveog4xf1pZL4PfRxNoVL7a/jw==} - - retext-stringify@3.1.0: - resolution: {integrity: sha512-767TLOaoXFXyOnjx/EggXlb37ZD2u4P1n0GJqVdpipqACsQP+20W+BNpMYrlJkq7hxffnFk+jc6mAK9qrbuB8w==} - - retext@8.1.0: - resolution: {integrity: sha512-N9/Kq7YTn6ZpzfiGW45WfEGJqFf1IM1q8OsRa1CGzIebCJBNCANDRmOrholiDRGKo/We7ofKR4SEvcGAWEMD3Q==} - - robust-predicates@3.0.2: - resolution: {integrity: sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==} - - rw@1.3.3: - resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==} - - sade@1.8.1: - resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} - engines: {node: '>=6'} - - safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - - scheduler@0.23.0: - resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==} - - scroll-into-view-if-needed@3.1.0: - resolution: {integrity: sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==} - - section-matter@1.0.0: - resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==} - engines: {node: '>=4'} - - shebang-command@1.2.0: - resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} - engines: {node: '>=0.10.0'} - - shebang-regex@1.0.0: - resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} - engines: {node: '>=0.10.0'} - - shiki@1.6.1: - resolution: {integrity: sha512-1Pu/A1rtsG6HZvQm4W0NExQ45e02og+rPog7PDaFDiMumZgOYnZIu4JtGQeAIfMwdbKSjJQoCUr79vDLKUUxWA==} - - signal-exit@3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - - slash@5.1.0: - resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==} - engines: {node: '>=14.16'} - - source-map-js@1.0.2: - resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} - engines: {node: '>=0.10.0'} - - source-map@0.7.4: - resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} - engines: {node: '>= 8'} - - space-separated-tokens@2.0.2: - resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} - - speech-rule-engine@4.0.7: - resolution: {integrity: sha512-sJrL3/wHzNwJRLBdf6CjJWIlxC04iYKkyXvYSVsWVOiC2DSkHmxsqOhEeMsBA9XK+CHuNcsdkbFDnoUfAsmp9g==} - hasBin: true - - sprintf-js@1.0.3: - resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - - streamsearch@1.1.0: - resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} - engines: {node: '>=10.0.0'} - - stringify-entities@4.0.3: - resolution: {integrity: sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g==} - - strip-bom-string@1.0.0: - resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==} - engines: {node: '>=0.10.0'} - - strip-eof@1.0.0: - resolution: {integrity: sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==} - engines: {node: '>=0.10.0'} - - style-to-object@0.4.4: - resolution: {integrity: sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==} - - style-to-object@1.0.6: - resolution: {integrity: sha512-khxq+Qm3xEyZfKd/y9L3oIWQimxuc4STrQKtQn8aSDRHb8mFgpukgX1hdzfrMEW6JCjyJ8p89x+IUMVnCBI1PA==} - - styled-jsx@5.1.1: - resolution: {integrity: sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==} - engines: {node: '>= 12.0.0'} - peerDependencies: - '@babel/core': '*' - babel-plugin-macros: '*' - react: '>= 16.8.0 || 17.x.x || ^18.0.0-0' - peerDependenciesMeta: - '@babel/core': - optional: true - babel-plugin-macros: - optional: true - - stylis@4.3.1: - resolution: {integrity: sha512-EQepAV+wMsIaGVGX1RECzgrcqRRU/0sYOHkeLsZ3fzHaHXZy4DaOOX0vOlGQdlsjkh3mFHAIlVimpwAs4dslyQ==} - - supports-color@4.5.0: - resolution: {integrity: sha512-ycQR/UbvI9xIlEdQT1TQqwoXtEldExbCEAJgRo5YXlmSKjv6ThHnP9/vwGa1gr19Gfw+LkFd7KqYMhzrRC5JYw==} - engines: {node: '>=4'} - - title@3.5.3: - resolution: {integrity: sha512-20JyowYglSEeCvZv3EZ0nZ046vLarO37prvV0mbtQV7C8DJPGgN967r8SJkqd3XK3K3lD3/Iyfp3avjfil8Q2Q==} - hasBin: true - - titleize@1.0.0: - resolution: {integrity: sha512-TARUb7z1pGvlLxgPk++7wJ6aycXF3GJ0sNSBTAsTuJrQG5QuZlkUQP+zl+nbjAh4gMX9yDw9ZYklMd7vAfJKEw==} - engines: {node: '>=0.10.0'} - - trim-lines@3.0.1: - resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} - - trough@2.1.0: - resolution: {integrity: sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==} - - ts-dedent@2.2.0: - resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==} - engines: {node: '>=6.10'} - - tslib@2.4.1: - resolution: {integrity: sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==} - - twoslash-protocol@0.2.6: - resolution: {integrity: sha512-8NbJlYeRdBcCTQ7ui7pdRPC1NL16aOnoYNz06oBW+W0qWNuiQXHgE8UeNvbA038aDd6ZPuuD5WedsBIESocB4g==} - - twoslash@0.2.6: - resolution: {integrity: sha512-DcAKIyXMB6xNs+SOw/oF8GvUr/cfJSqznngVXYbAUIVfTW3M8vWSEoCaz/RgSD+M6vwtK8DJ4/FmYBF5MN8BGw==} - peerDependencies: - typescript: '*' - - typescript@5.3.3: - resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==} - engines: {node: '>=14.17'} - hasBin: true - - undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - - unherit@3.0.1: - resolution: {integrity: sha512-akOOQ/Yln8a2sgcLj4U0Jmx0R5jpIg2IUyRrWOzmEbjBtGzBdHtSeFKgoEcoH4KYIG/Pb8GQ/BwtYm0GCq1Sqg==} - - unified@10.1.2: - resolution: {integrity: sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==} - - unified@11.0.4: - resolution: {integrity: sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==} - - unist-util-find-after@5.0.0: - resolution: {integrity: sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==} - - unist-util-is@5.1.1: - resolution: {integrity: sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==} - - unist-util-is@6.0.0: - resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==} - - unist-util-modify-children@3.1.1: - resolution: {integrity: sha512-yXi4Lm+TG5VG+qvokP6tpnk+r1EPwyYL04JWDxLvgvPV40jANh7nm3udk65OOWquvbMDe+PL9+LmkxDpTv/7BA==} - - unist-util-position-from-estree@2.0.0: - resolution: {integrity: sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==} - - unist-util-position@5.0.0: - resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} - - unist-util-remove-position@5.0.0: - resolution: {integrity: sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==} - - unist-util-remove@4.0.0: - resolution: {integrity: sha512-b4gokeGId57UVRX/eVKej5gXqGlc9+trkORhFJpu9raqZkZhU0zm8Doi05+HaiBsMEIJowL+2WtQ5ItjsngPXg==} - - unist-util-stringify-position@3.0.2: - resolution: {integrity: sha512-7A6eiDCs9UtjcwZOcCpM4aPII3bAAGv13E96IkawkOAW0OhH+yRxtY0lzo8KiHpzEMfH7Q+FizUmwp8Iqy5EWg==} - - unist-util-stringify-position@4.0.0: - resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} - - unist-util-visit-children@2.0.2: - resolution: {integrity: sha512-+LWpMFqyUwLGpsQxpumsQ9o9DG2VGLFrpz+rpVXYIEdPy57GSy5HioC0g3bg/8WP9oCLlapQtklOzQ8uLS496Q==} - - unist-util-visit-parents@4.1.1: - resolution: {integrity: sha512-1xAFJXAKpnnJl8G7K5KgU7FY55y3GcLIXqkzUj5QF/QVP7biUm0K0O2oqVkYsdjzJKifYeWn9+o6piAK2hGSHw==} - - unist-util-visit-parents@5.1.1: - resolution: {integrity: sha512-gks4baapT/kNRaWxuGkl5BIhoanZo7sC/cUT/JToSRNL1dYoXRFl75d++NkjYk4TAu2uv2Px+l8guMajogeuiw==} - - unist-util-visit-parents@6.0.1: - resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==} - - unist-util-visit@3.1.0: - resolution: {integrity: sha512-Szoh+R/Ll68QWAyQyZZpQzZQm2UPbxibDvaY8Xc9SUtYgPsDzx5AWSk++UUt2hJuow8mvwR+rG+LQLw+KsuAKA==} - - unist-util-visit@4.1.1: - resolution: {integrity: sha512-n9KN3WV9k4h1DxYR1LoajgN93wpEi/7ZplVe02IoB4gH5ctI1AaF2670BLHQYbwj+pY83gFtyeySFiyMHJklrg==} - - unist-util-visit@5.0.0: - resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} - - uuid@9.0.1: - resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} - hasBin: true - - uvu@0.5.6: - resolution: {integrity: sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==} - engines: {node: '>=8'} - hasBin: true - - vfile-location@5.0.2: - resolution: {integrity: sha512-NXPYyxyBSH7zB5U6+3uDdd6Nybz6o6/od9rk8bp9H8GR3L+cm/fC0uUTbqBmUTnMCUDslAGBOIKNfvvb+gGlDg==} - - vfile-message@3.1.3: - resolution: {integrity: sha512-0yaU+rj2gKAyEk12ffdSbBfjnnj+b1zqTBv3OQCTn8yEB02bsPizwdBPrLJjHnK+cU9EMMcUnNv938XcZIkmdA==} - - vfile-message@4.0.2: - resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==} - - vfile@5.3.6: - resolution: {integrity: sha512-ADBsmerdGBs2WYckrLBEmuETSPyTD4TuLxTrw0DvjirxW1ra4ZwkbzG8ndsv3Q57smvHxo677MHaQrY9yxH8cA==} - - vfile@6.0.1: - resolution: {integrity: sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==} - - web-namespaces@2.0.1: - resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} - - web-worker@1.3.0: - resolution: {integrity: sha512-BSR9wyRsy/KOValMgd5kMyr3JzpdeoR9KVId8u5GVlTTAtNChlsE4yTxeY7zMdNSyOmoKBv8NH2qeRY9Tg+IaA==} - - which@1.3.1: - resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} - hasBin: true - - wicked-good-xpath@1.3.0: - resolution: {integrity: sha512-Gd9+TUn5nXdwj/hFsPVx5cuHHiF5Bwuc30jZ4+ronF1qHK5O7HD0sgmXWSEgwKquT3ClLoKPVbO6qGwVwLzvAw==} - - xmldom-sre@0.1.31: - resolution: {integrity: sha512-f9s+fUkX04BxQf+7mMWAp5zk61pciie+fFLC9hX9UVvCeJQfNHRHXpeo5MPcR0EUf57PYLdt+ZO4f3Ipk2oZUw==} - engines: {node: '>=0.1'} - - yallist@2.1.2: - resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==} - - yaml@2.4.2: - resolution: {integrity: sha512-B3VqDZ+JAg1nZpaEmWtTXUlBneoGx6CPM9b0TENK6aoSu5t73dItudwdgmi6tHlIZZId4dZ9skcAQ2UbcyAeVA==} - engines: {node: '>= 14'} - hasBin: true - - yocto-queue@1.0.0: - resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} - engines: {node: '>=12.20'} - - zod-validation-error@1.5.0: - resolution: {integrity: sha512-/7eFkAI4qV0tcxMBB/3+d2c1P6jzzZYdYSlBuAklzMuCrJu5bzJfHS0yVAS87dRHVlhftd6RFJDIvv03JgkSbw==} - engines: {node: '>=16.0.0'} - peerDependencies: - zod: ^3.18.0 - - zod@3.22.4: - resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} - - zwitch@2.0.4: - resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} - -snapshots: - - '@braintree/sanitize-url@6.0.4': {} - - '@headlessui/react@1.7.18(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': - dependencies: - '@tanstack/react-virtual': 3.1.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - client-only: 0.0.1 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - - '@mdx-js/mdx@3.0.1': - dependencies: - '@types/estree': 1.0.0 - '@types/estree-jsx': 1.0.0 - '@types/hast': 3.0.4 - '@types/mdx': 2.0.3 - collapse-white-space: 2.1.0 - devlop: 1.1.0 - estree-util-build-jsx: 3.0.1 - estree-util-is-identifier-name: 3.0.0 - estree-util-to-js: 2.0.0 - estree-walker: 3.0.1 - hast-util-to-estree: 3.1.0 - hast-util-to-jsx-runtime: 2.3.0 - markdown-extensions: 2.0.0 - periscopic: 3.0.4 - remark-mdx: 3.0.1 - remark-parse: 11.0.0 - remark-rehype: 11.1.0 - source-map: 0.7.4 - unified: 11.0.4 - unist-util-position-from-estree: 2.0.0 - unist-util-stringify-position: 4.0.0 - unist-util-visit: 5.0.0 - vfile: 6.0.1 - transitivePeerDependencies: - - supports-color - - '@mdx-js/react@3.0.1(@types/react@18.0.26)(react@18.2.0)': - dependencies: - '@types/mdx': 2.0.3 - '@types/react': 18.0.26 - react: 18.2.0 - - '@napi-rs/simple-git-android-arm-eabi@0.1.16': - optional: true - - '@napi-rs/simple-git-android-arm64@0.1.16': - optional: true - - '@napi-rs/simple-git-darwin-arm64@0.1.16': - optional: true - - '@napi-rs/simple-git-darwin-x64@0.1.16': - optional: true - - '@napi-rs/simple-git-linux-arm-gnueabihf@0.1.16': - optional: true - - '@napi-rs/simple-git-linux-arm64-gnu@0.1.16': - optional: true - - '@napi-rs/simple-git-linux-arm64-musl@0.1.16': - optional: true - - '@napi-rs/simple-git-linux-x64-gnu@0.1.16': - optional: true - - '@napi-rs/simple-git-linux-x64-musl@0.1.16': - optional: true - - '@napi-rs/simple-git-win32-arm64-msvc@0.1.16': - optional: true - - '@napi-rs/simple-git-win32-x64-msvc@0.1.16': - optional: true - - '@napi-rs/simple-git@0.1.16': - optionalDependencies: - '@napi-rs/simple-git-android-arm-eabi': 0.1.16 - '@napi-rs/simple-git-android-arm64': 0.1.16 - '@napi-rs/simple-git-darwin-arm64': 0.1.16 - '@napi-rs/simple-git-darwin-x64': 0.1.16 - '@napi-rs/simple-git-linux-arm-gnueabihf': 0.1.16 - '@napi-rs/simple-git-linux-arm64-gnu': 0.1.16 - '@napi-rs/simple-git-linux-arm64-musl': 0.1.16 - '@napi-rs/simple-git-linux-x64-gnu': 0.1.16 - '@napi-rs/simple-git-linux-x64-musl': 0.1.16 - '@napi-rs/simple-git-win32-arm64-msvc': 0.1.16 - '@napi-rs/simple-git-win32-x64-msvc': 0.1.16 - - '@next/env@14.1.1': {} - - '@next/swc-darwin-arm64@14.1.1': - optional: true - - '@next/swc-darwin-x64@14.1.1': - optional: true - - '@next/swc-linux-arm64-gnu@14.1.1': - optional: true - - '@next/swc-linux-arm64-musl@14.1.1': - optional: true - - '@next/swc-linux-x64-gnu@14.1.1': - optional: true - - '@next/swc-linux-x64-musl@14.1.1': - optional: true - - '@next/swc-win32-arm64-msvc@14.1.1': - optional: true - - '@next/swc-win32-ia32-msvc@14.1.1': - optional: true - - '@next/swc-win32-x64-msvc@14.1.1': - optional: true - - '@popperjs/core@2.11.8': {} - - '@shikijs/core@1.6.1': {} - - '@shikijs/twoslash@1.6.1(typescript@5.3.3)': - dependencies: - '@shikijs/core': 1.6.1 - twoslash: 0.2.6(typescript@5.3.3) - transitivePeerDependencies: - - supports-color - - typescript - - '@swc/helpers@0.5.2': - dependencies: - tslib: 2.4.1 - - '@tanstack/react-virtual@3.1.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': - dependencies: - '@tanstack/virtual-core': 3.1.3 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - - '@tanstack/virtual-core@3.1.3': {} - - '@theguild/remark-mermaid@0.0.5(react@18.2.0)': - dependencies: - mermaid: 10.8.0 - react: 18.2.0 - unist-util-visit: 5.0.0 - transitivePeerDependencies: - - supports-color - - '@theguild/remark-npm2yarn@0.3.0': - dependencies: - npm-to-yarn: 2.2.1 - unist-util-visit: 5.0.0 - - '@types/acorn@4.0.6': - dependencies: - '@types/estree': 1.0.0 - - '@types/d3-scale-chromatic@3.0.3': {} - - '@types/d3-scale@4.0.8': - dependencies: - '@types/d3-time': 3.0.3 - - '@types/d3-time@3.0.3': {} - - '@types/debug@4.1.7': - dependencies: - '@types/ms': 0.7.31 - - '@types/estree-jsx@1.0.0': - dependencies: - '@types/estree': 1.0.0 - - '@types/estree@1.0.0': {} - - '@types/hast@3.0.4': - dependencies: - '@types/unist': 3.0.2 - - '@types/katex@0.16.7': {} - - '@types/mdast@3.0.10': - dependencies: - '@types/unist': 3.0.2 - - '@types/mdast@4.0.3': - dependencies: - '@types/unist': 3.0.2 - - '@types/mdx@2.0.3': {} - - '@types/ms@0.7.31': {} - - '@types/nlcst@1.0.4': - dependencies: - '@types/unist': 2.0.6 - - '@types/node@20.11.24': - dependencies: - undici-types: 5.26.5 - - '@types/prop-types@15.7.5': {} - - '@types/react@18.0.26': - dependencies: - '@types/prop-types': 15.7.5 - '@types/scheduler': 0.16.2 - csstype: 3.1.1 - - '@types/scheduler@0.16.2': {} - - '@types/unist@2.0.6': {} - - '@types/unist@3.0.2': {} - - '@typescript/vfs@1.5.0': - dependencies: - debug: 4.3.4 - transitivePeerDependencies: - - supports-color - - '@ungap/structured-clone@1.2.0': {} - - acorn-jsx@5.3.2(acorn@8.8.1): - dependencies: - acorn: 8.8.1 - - acorn@8.8.1: {} - - ansi-styles@3.2.1: - dependencies: - color-convert: 1.9.3 - - arch@2.2.0: {} - - arg@1.0.0: {} - - argparse@1.0.10: - dependencies: - sprintf-js: 1.0.3 - - array-iterate@2.0.1: {} - - astring@1.8.3: {} - - bail@2.0.2: {} - - better-react-mathjax@2.0.3(react@18.2.0): - dependencies: - mathjax-full: 3.2.2 - react: 18.2.0 - - busboy@1.6.0: - dependencies: - streamsearch: 1.1.0 - - caniuse-lite@1.0.30001591: {} - - ccount@2.0.1: {} - - chalk@2.3.0: - dependencies: - ansi-styles: 3.2.1 - escape-string-regexp: 1.0.5 - supports-color: 4.5.0 - - character-entities-html4@2.1.0: {} - - character-entities-legacy@3.0.0: {} - - character-entities@2.0.2: {} - - character-reference-invalid@2.0.1: {} - - client-only@0.0.1: {} - - clipboardy@1.2.2: - dependencies: - arch: 2.2.0 - execa: 0.8.0 - - clsx@2.1.0: {} - - collapse-white-space@2.1.0: {} - - color-convert@1.9.3: - dependencies: - color-name: 1.1.3 - - color-name@1.1.3: {} - - comma-separated-tokens@2.0.3: {} - - commander@7.2.0: {} - - commander@8.3.0: {} - - commander@9.2.0: {} - - compute-scroll-into-view@3.1.0: {} - - cose-base@1.0.3: - dependencies: - layout-base: 1.0.2 - - cross-spawn@5.1.0: - dependencies: - lru-cache: 4.1.5 - shebang-command: 1.2.0 - which: 1.3.1 - - csstype@3.1.1: {} - - cytoscape-cose-bilkent@4.1.0(cytoscape@3.28.1): - dependencies: - cose-base: 1.0.3 - cytoscape: 3.28.1 - - cytoscape@3.28.1: - dependencies: - heap: 0.2.7 - lodash: 4.17.21 - - d3-array@2.12.1: - dependencies: - internmap: 1.0.1 - - d3-array@3.2.4: - dependencies: - internmap: 2.0.3 - - d3-axis@3.0.0: {} - - d3-brush@3.0.0: - dependencies: - d3-dispatch: 3.0.1 - d3-drag: 3.0.0 - d3-interpolate: 3.0.1 - d3-selection: 3.0.0 - d3-transition: 3.0.1(d3-selection@3.0.0) - - d3-chord@3.0.1: - dependencies: - d3-path: 3.1.0 - - d3-color@3.1.0: {} - - d3-contour@4.0.2: - dependencies: - d3-array: 3.2.4 - - d3-delaunay@6.0.4: - dependencies: - delaunator: 5.0.1 - - d3-dispatch@3.0.1: {} - - d3-drag@3.0.0: - dependencies: - d3-dispatch: 3.0.1 - d3-selection: 3.0.0 - - d3-dsv@3.0.1: - dependencies: - commander: 7.2.0 - iconv-lite: 0.6.3 - rw: 1.3.3 - - d3-ease@3.0.1: {} - - d3-fetch@3.0.1: - dependencies: - d3-dsv: 3.0.1 - - d3-force@3.0.0: - dependencies: - d3-dispatch: 3.0.1 - d3-quadtree: 3.0.1 - d3-timer: 3.0.1 - - d3-format@3.1.0: {} - - d3-geo@3.1.0: - dependencies: - d3-array: 3.2.4 - - d3-hierarchy@3.1.2: {} - - d3-interpolate@3.0.1: - dependencies: - d3-color: 3.1.0 - - d3-path@1.0.9: {} - - d3-path@3.1.0: {} - - d3-polygon@3.0.1: {} - - d3-quadtree@3.0.1: {} - - d3-random@3.0.1: {} - - d3-sankey@0.12.3: - dependencies: - d3-array: 2.12.1 - d3-shape: 1.3.7 - - d3-scale-chromatic@3.0.0: - dependencies: - d3-color: 3.1.0 - d3-interpolate: 3.0.1 - - d3-scale@4.0.2: - dependencies: - d3-array: 3.2.4 - d3-format: 3.1.0 - d3-interpolate: 3.0.1 - d3-time: 3.1.0 - d3-time-format: 4.1.0 - - d3-selection@3.0.0: {} - - d3-shape@1.3.7: - dependencies: - d3-path: 1.0.9 - - d3-shape@3.2.0: - dependencies: - d3-path: 3.1.0 - - d3-time-format@4.1.0: - dependencies: - d3-time: 3.1.0 - - d3-time@3.1.0: - dependencies: - d3-array: 3.2.4 - - d3-timer@3.0.1: {} - - d3-transition@3.0.1(d3-selection@3.0.0): - dependencies: - d3-color: 3.1.0 - d3-dispatch: 3.0.1 - d3-ease: 3.0.1 - d3-interpolate: 3.0.1 - d3-selection: 3.0.0 - d3-timer: 3.0.1 - - d3-zoom@3.0.0: - dependencies: - d3-dispatch: 3.0.1 - d3-drag: 3.0.0 - d3-interpolate: 3.0.1 - d3-selection: 3.0.0 - d3-transition: 3.0.1(d3-selection@3.0.0) - - d3@7.8.5: - dependencies: - d3-array: 3.2.4 - d3-axis: 3.0.0 - d3-brush: 3.0.0 - d3-chord: 3.0.1 - d3-color: 3.1.0 - d3-contour: 4.0.2 - d3-delaunay: 6.0.4 - d3-dispatch: 3.0.1 - d3-drag: 3.0.0 - d3-dsv: 3.0.1 - d3-ease: 3.0.1 - d3-fetch: 3.0.1 - d3-force: 3.0.0 - d3-format: 3.1.0 - d3-geo: 3.1.0 - d3-hierarchy: 3.1.2 - d3-interpolate: 3.0.1 - d3-path: 3.1.0 - d3-polygon: 3.0.1 - d3-quadtree: 3.0.1 - d3-random: 3.0.1 - d3-scale: 4.0.2 - d3-scale-chromatic: 3.0.0 - d3-selection: 3.0.0 - d3-shape: 3.2.0 - d3-time: 3.1.0 - d3-time-format: 4.1.0 - d3-timer: 3.0.1 - d3-transition: 3.0.1(d3-selection@3.0.0) - d3-zoom: 3.0.0 - - dagre-d3-es@7.0.10: - dependencies: - d3: 7.8.5 - lodash-es: 4.17.21 - - dayjs@1.11.10: {} - - debug@4.3.4: - dependencies: - ms: 2.1.2 - - decode-named-character-reference@1.0.2: - dependencies: - character-entities: 2.0.2 - - delaunator@5.0.1: - dependencies: - robust-predicates: 3.0.2 - - dequal@2.0.3: {} - - devlop@1.1.0: - dependencies: - dequal: 2.0.3 - - diff@5.1.0: {} - - dompurify@3.0.9: {} - - elkjs@0.9.2: {} - - entities@4.5.0: {} - - escape-string-regexp@1.0.5: {} - - escape-string-regexp@5.0.0: {} - - esm@3.2.25: {} - - esprima@4.0.1: {} - - estree-util-attach-comments@3.0.0: - dependencies: - '@types/estree': 1.0.0 - - estree-util-build-jsx@3.0.1: - dependencies: - '@types/estree-jsx': 1.0.0 - devlop: 1.1.0 - estree-util-is-identifier-name: 3.0.0 - estree-walker: 3.0.1 - - estree-util-is-identifier-name@2.0.1: {} - - estree-util-is-identifier-name@3.0.0: {} - - estree-util-to-js@2.0.0: - dependencies: - '@types/estree-jsx': 1.0.0 - astring: 1.8.3 - source-map: 0.7.4 - - estree-util-value-to-estree@1.3.0: - dependencies: - is-plain-obj: 3.0.0 - - estree-util-value-to-estree@3.1.1: - dependencies: - '@types/estree': 1.0.0 - is-plain-obj: 4.1.0 - - estree-util-visit@2.0.0: - dependencies: - '@types/estree-jsx': 1.0.0 - '@types/unist': 3.0.2 - - estree-walker@3.0.1: {} - - execa@0.8.0: - dependencies: - cross-spawn: 5.1.0 - get-stream: 3.0.0 - is-stream: 1.1.0 - npm-run-path: 2.0.2 - p-finally: 1.0.0 - signal-exit: 3.0.7 - strip-eof: 1.0.0 - - extend-shallow@2.0.1: - dependencies: - is-extendable: 0.1.1 - - extend@3.0.2: {} - - fault@2.0.1: - dependencies: - format: 0.2.2 - - flexsearch@0.7.43: {} - - focus-visible@5.2.0: {} - - format@0.2.2: {} - - get-stream@3.0.0: {} - - github-slugger@2.0.0: {} - - graceful-fs@4.2.11: {} - - gray-matter@4.0.3: - dependencies: - js-yaml: 3.14.1 - kind-of: 6.0.3 - section-matter: 1.0.0 - strip-bom-string: 1.0.0 - - has-flag@2.0.0: {} - - hast-util-from-dom@5.0.0: - dependencies: - '@types/hast': 3.0.4 - hastscript: 8.0.0 - web-namespaces: 2.0.1 - - hast-util-from-html-isomorphic@2.0.0: - dependencies: - '@types/hast': 3.0.4 - hast-util-from-dom: 5.0.0 - hast-util-from-html: 2.0.1 - unist-util-remove-position: 5.0.0 - - hast-util-from-html@2.0.1: - dependencies: - '@types/hast': 3.0.4 - devlop: 1.1.0 - hast-util-from-parse5: 8.0.1 - parse5: 7.1.2 - vfile: 6.0.1 - vfile-message: 4.0.2 - - hast-util-from-parse5@8.0.1: - dependencies: - '@types/hast': 3.0.4 - '@types/unist': 3.0.2 - devlop: 1.1.0 - hastscript: 8.0.0 - property-information: 6.2.0 - vfile: 6.0.1 - vfile-location: 5.0.2 - web-namespaces: 2.0.1 - - hast-util-is-element@3.0.0: - dependencies: - '@types/hast': 3.0.4 - - hast-util-parse-selector@4.0.0: - dependencies: - '@types/hast': 3.0.4 - - hast-util-raw@9.0.2: - dependencies: - '@types/hast': 3.0.4 - '@types/unist': 3.0.2 - '@ungap/structured-clone': 1.2.0 - hast-util-from-parse5: 8.0.1 - hast-util-to-parse5: 8.0.0 - html-void-elements: 3.0.0 - mdast-util-to-hast: 13.1.0 - parse5: 7.1.2 - unist-util-position: 5.0.0 - unist-util-visit: 5.0.0 - vfile: 6.0.1 - web-namespaces: 2.0.1 - zwitch: 2.0.4 - - hast-util-to-estree@3.1.0: - dependencies: - '@types/estree': 1.0.0 - '@types/estree-jsx': 1.0.0 - '@types/hast': 3.0.4 - comma-separated-tokens: 2.0.3 - devlop: 1.1.0 - estree-util-attach-comments: 3.0.0 - estree-util-is-identifier-name: 3.0.0 - hast-util-whitespace: 3.0.0 - mdast-util-mdx-expression: 2.0.0 - mdast-util-mdx-jsx: 3.1.2 - mdast-util-mdxjs-esm: 2.0.1 - property-information: 6.2.0 - space-separated-tokens: 2.0.2 - style-to-object: 0.4.4 - unist-util-position: 5.0.0 - zwitch: 2.0.4 - transitivePeerDependencies: - - supports-color - - hast-util-to-jsx-runtime@2.3.0: - dependencies: - '@types/estree': 1.0.0 - '@types/hast': 3.0.4 - '@types/unist': 3.0.2 - comma-separated-tokens: 2.0.3 - devlop: 1.1.0 - estree-util-is-identifier-name: 3.0.0 - hast-util-whitespace: 3.0.0 - mdast-util-mdx-expression: 2.0.0 - mdast-util-mdx-jsx: 3.1.2 - mdast-util-mdxjs-esm: 2.0.1 - property-information: 6.2.0 - space-separated-tokens: 2.0.2 - style-to-object: 1.0.6 - unist-util-position: 5.0.0 - vfile-message: 4.0.2 - transitivePeerDependencies: - - supports-color - - hast-util-to-parse5@8.0.0: - dependencies: - '@types/hast': 3.0.4 - comma-separated-tokens: 2.0.3 - devlop: 1.1.0 - property-information: 6.2.0 - space-separated-tokens: 2.0.2 - web-namespaces: 2.0.1 - zwitch: 2.0.4 - - hast-util-to-string@3.0.0: - dependencies: - '@types/hast': 3.0.4 - - hast-util-to-text@4.0.0: - dependencies: - '@types/hast': 3.0.4 - '@types/unist': 3.0.2 - hast-util-is-element: 3.0.0 - unist-util-find-after: 5.0.0 - - hast-util-whitespace@3.0.0: - dependencies: - '@types/hast': 3.0.4 - - hastscript@8.0.0: - dependencies: - '@types/hast': 3.0.4 - comma-separated-tokens: 2.0.3 - hast-util-parse-selector: 4.0.0 - property-information: 6.2.0 - space-separated-tokens: 2.0.2 - - heap@0.2.7: {} - - html-void-elements@3.0.0: {} - - iconv-lite@0.6.3: - dependencies: - safer-buffer: 2.1.2 - - inline-style-parser@0.1.1: {} - - inline-style-parser@0.2.3: {} - - internmap@1.0.1: {} - - internmap@2.0.3: {} - - intersection-observer@0.12.2: {} - - is-alphabetical@2.0.1: {} - - is-alphanumerical@2.0.1: - dependencies: - is-alphabetical: 2.0.1 - is-decimal: 2.0.1 - - is-buffer@2.0.5: {} - - is-decimal@2.0.1: {} - - is-extendable@0.1.1: {} - - is-hexadecimal@2.0.1: {} - - is-plain-obj@3.0.0: {} - - is-plain-obj@4.1.0: {} - - is-reference@3.0.0: - dependencies: - '@types/estree': 1.0.0 - - is-stream@1.1.0: {} - - isexe@2.0.0: {} - - js-tokens@4.0.0: {} - - js-yaml@3.14.1: - dependencies: - argparse: 1.0.10 - esprima: 4.0.1 - - katex@0.16.9: - dependencies: - commander: 8.3.0 - - khroma@2.1.0: {} - - kind-of@6.0.3: {} - - kleur@4.1.5: {} - - layout-base@1.0.2: {} - - lodash-es@4.17.21: {} - - lodash@4.17.21: {} - - longest-streak@3.1.0: {} - - loose-envify@1.4.0: - dependencies: - js-tokens: 4.0.0 - - lru-cache@4.1.5: - dependencies: - pseudomap: 1.0.2 - yallist: 2.1.2 - - markdown-extensions@2.0.0: {} - - markdown-table@3.0.3: {} - - mathjax-full@3.2.2: - dependencies: - esm: 3.2.25 - mhchemparser: 4.2.1 - mj-context-menu: 0.6.1 - speech-rule-engine: 4.0.7 - - mdast-util-find-and-replace@3.0.1: - dependencies: - '@types/mdast': 4.0.3 - escape-string-regexp: 5.0.0 - unist-util-is: 6.0.0 - unist-util-visit-parents: 6.0.1 - - mdast-util-from-markdown@1.3.1: - dependencies: - '@types/mdast': 3.0.10 - '@types/unist': 2.0.6 - decode-named-character-reference: 1.0.2 - mdast-util-to-string: 3.1.0 - micromark: 3.1.0 - micromark-util-decode-numeric-character-reference: 1.0.0 - micromark-util-decode-string: 1.0.2 - micromark-util-normalize-identifier: 1.0.0 - micromark-util-symbol: 1.0.1 - micromark-util-types: 1.0.2 - unist-util-stringify-position: 3.0.2 - uvu: 0.5.6 - transitivePeerDependencies: - - supports-color - - mdast-util-from-markdown@2.0.1: - dependencies: - '@types/mdast': 4.0.3 - '@types/unist': 3.0.2 - decode-named-character-reference: 1.0.2 - devlop: 1.1.0 - mdast-util-to-string: 4.0.0 - micromark: 4.0.0 - micromark-util-decode-numeric-character-reference: 2.0.1 - micromark-util-decode-string: 2.0.0 - micromark-util-normalize-identifier: 2.0.0 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 - unist-util-stringify-position: 4.0.0 - transitivePeerDependencies: - - supports-color - - mdast-util-frontmatter@2.0.1: - dependencies: - '@types/mdast': 4.0.3 - devlop: 1.1.0 - escape-string-regexp: 5.0.0 - mdast-util-from-markdown: 2.0.1 - mdast-util-to-markdown: 2.1.0 - micromark-extension-frontmatter: 2.0.0 - transitivePeerDependencies: - - supports-color - - mdast-util-gfm-autolink-literal@2.0.0: - dependencies: - '@types/mdast': 4.0.3 - ccount: 2.0.1 - devlop: 1.1.0 - mdast-util-find-and-replace: 3.0.1 - micromark-util-character: 2.1.0 - - mdast-util-gfm-footnote@2.0.0: - dependencies: - '@types/mdast': 4.0.3 - devlop: 1.1.0 - mdast-util-from-markdown: 2.0.1 - mdast-util-to-markdown: 2.1.0 - micromark-util-normalize-identifier: 2.0.0 - transitivePeerDependencies: - - supports-color - - mdast-util-gfm-strikethrough@2.0.0: - dependencies: - '@types/mdast': 4.0.3 - mdast-util-from-markdown: 2.0.1 - mdast-util-to-markdown: 2.1.0 - transitivePeerDependencies: - - supports-color - - mdast-util-gfm-table@2.0.0: - dependencies: - '@types/mdast': 4.0.3 - devlop: 1.1.0 - markdown-table: 3.0.3 - mdast-util-from-markdown: 2.0.1 - mdast-util-to-markdown: 2.1.0 - transitivePeerDependencies: - - supports-color - - mdast-util-gfm-task-list-item@2.0.0: - dependencies: - '@types/mdast': 4.0.3 - devlop: 1.1.0 - mdast-util-from-markdown: 2.0.1 - mdast-util-to-markdown: 2.1.0 - transitivePeerDependencies: - - supports-color - - mdast-util-gfm@3.0.0: - dependencies: - mdast-util-from-markdown: 2.0.1 - mdast-util-gfm-autolink-literal: 2.0.0 - mdast-util-gfm-footnote: 2.0.0 - mdast-util-gfm-strikethrough: 2.0.0 - mdast-util-gfm-table: 2.0.0 - mdast-util-gfm-task-list-item: 2.0.0 - mdast-util-to-markdown: 2.1.0 - transitivePeerDependencies: - - supports-color - - mdast-util-math@3.0.0: - dependencies: - '@types/hast': 3.0.4 - '@types/mdast': 4.0.3 - devlop: 1.1.0 - longest-streak: 3.1.0 - mdast-util-from-markdown: 2.0.1 - mdast-util-to-markdown: 2.1.0 - unist-util-remove-position: 5.0.0 - transitivePeerDependencies: - - supports-color - - mdast-util-mdx-expression@2.0.0: - dependencies: - '@types/estree-jsx': 1.0.0 - '@types/hast': 3.0.4 - '@types/mdast': 4.0.3 - devlop: 1.1.0 - mdast-util-from-markdown: 2.0.1 - mdast-util-to-markdown: 2.1.0 - transitivePeerDependencies: - - supports-color - - mdast-util-mdx-jsx@3.1.2: - dependencies: - '@types/estree-jsx': 1.0.0 - '@types/hast': 3.0.4 - '@types/mdast': 4.0.3 - '@types/unist': 3.0.2 - ccount: 2.0.1 - devlop: 1.1.0 - mdast-util-from-markdown: 2.0.1 - mdast-util-to-markdown: 2.1.0 - parse-entities: 4.0.0 - stringify-entities: 4.0.3 - unist-util-remove-position: 5.0.0 - unist-util-stringify-position: 4.0.0 - vfile-message: 4.0.2 - transitivePeerDependencies: - - supports-color - - mdast-util-mdx@3.0.0: - dependencies: - mdast-util-from-markdown: 2.0.1 - mdast-util-mdx-expression: 2.0.0 - mdast-util-mdx-jsx: 3.1.2 - mdast-util-mdxjs-esm: 2.0.1 - mdast-util-to-markdown: 2.1.0 - transitivePeerDependencies: - - supports-color - - mdast-util-mdxjs-esm@2.0.1: - dependencies: - '@types/estree-jsx': 1.0.0 - '@types/hast': 3.0.4 - '@types/mdast': 4.0.3 - devlop: 1.1.0 - mdast-util-from-markdown: 2.0.1 - mdast-util-to-markdown: 2.1.0 - transitivePeerDependencies: - - supports-color - - mdast-util-phrasing@4.1.0: - dependencies: - '@types/mdast': 4.0.3 - unist-util-is: 6.0.0 - - mdast-util-to-hast@13.1.0: - dependencies: - '@types/hast': 3.0.4 - '@types/mdast': 4.0.3 - '@ungap/structured-clone': 1.2.0 - devlop: 1.1.0 - micromark-util-sanitize-uri: 2.0.0 - trim-lines: 3.0.1 - unist-util-position: 5.0.0 - unist-util-visit: 5.0.0 - vfile: 6.0.1 - - mdast-util-to-markdown@2.1.0: - dependencies: - '@types/mdast': 4.0.3 - '@types/unist': 3.0.2 - longest-streak: 3.1.0 - mdast-util-phrasing: 4.1.0 - mdast-util-to-string: 4.0.0 - micromark-util-decode-string: 2.0.0 - unist-util-visit: 5.0.0 - zwitch: 2.0.4 - - mdast-util-to-string@3.1.0: {} - - mdast-util-to-string@4.0.0: - dependencies: - '@types/mdast': 4.0.3 - - mermaid@10.8.0: - dependencies: - '@braintree/sanitize-url': 6.0.4 - '@types/d3-scale': 4.0.8 - '@types/d3-scale-chromatic': 3.0.3 - cytoscape: 3.28.1 - cytoscape-cose-bilkent: 4.1.0(cytoscape@3.28.1) - d3: 7.8.5 - d3-sankey: 0.12.3 - dagre-d3-es: 7.0.10 - dayjs: 1.11.10 - dompurify: 3.0.9 - elkjs: 0.9.2 - khroma: 2.1.0 - lodash-es: 4.17.21 - mdast-util-from-markdown: 1.3.1 - non-layered-tidy-tree-layout: 2.0.2 - stylis: 4.3.1 - ts-dedent: 2.2.0 - uuid: 9.0.1 - web-worker: 1.3.0 - transitivePeerDependencies: - - supports-color - - mhchemparser@4.2.1: {} - - micromark-core-commonmark@1.0.6: - dependencies: - decode-named-character-reference: 1.0.2 - micromark-factory-destination: 1.0.0 - micromark-factory-label: 1.0.2 - micromark-factory-space: 1.0.0 - micromark-factory-title: 1.0.2 - micromark-factory-whitespace: 1.0.0 - micromark-util-character: 1.1.0 - micromark-util-chunked: 1.0.0 - micromark-util-classify-character: 1.0.0 - micromark-util-html-tag-name: 1.1.0 - micromark-util-normalize-identifier: 1.0.0 - micromark-util-resolve-all: 1.0.0 - micromark-util-subtokenize: 1.0.2 - micromark-util-symbol: 1.0.1 - micromark-util-types: 1.0.2 - uvu: 0.5.6 - - micromark-core-commonmark@2.0.1: - dependencies: - decode-named-character-reference: 1.0.2 - devlop: 1.1.0 - micromark-factory-destination: 2.0.0 - micromark-factory-label: 2.0.0 - micromark-factory-space: 2.0.0 - micromark-factory-title: 2.0.0 - micromark-factory-whitespace: 2.0.0 - micromark-util-character: 2.1.0 - micromark-util-chunked: 2.0.0 - micromark-util-classify-character: 2.0.0 - micromark-util-html-tag-name: 2.0.0 - micromark-util-normalize-identifier: 2.0.0 - micromark-util-resolve-all: 2.0.0 - micromark-util-subtokenize: 2.0.1 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 - - micromark-extension-frontmatter@2.0.0: - dependencies: - fault: 2.0.1 - micromark-util-character: 2.1.0 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 - - micromark-extension-gfm-autolink-literal@2.0.0: - dependencies: - micromark-util-character: 2.1.0 - micromark-util-sanitize-uri: 2.0.0 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 - - micromark-extension-gfm-footnote@2.0.0: - dependencies: - devlop: 1.1.0 - micromark-core-commonmark: 2.0.1 - micromark-factory-space: 2.0.0 - micromark-util-character: 2.1.0 - micromark-util-normalize-identifier: 2.0.0 - micromark-util-sanitize-uri: 2.0.0 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 - - micromark-extension-gfm-strikethrough@2.0.0: - dependencies: - devlop: 1.1.0 - micromark-util-chunked: 2.0.0 - micromark-util-classify-character: 2.0.0 - micromark-util-resolve-all: 2.0.0 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 - - micromark-extension-gfm-table@2.0.0: - dependencies: - devlop: 1.1.0 - micromark-factory-space: 2.0.0 - micromark-util-character: 2.1.0 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 - - micromark-extension-gfm-tagfilter@2.0.0: - dependencies: - micromark-util-types: 2.0.0 - - micromark-extension-gfm-task-list-item@2.0.1: - dependencies: - devlop: 1.1.0 - micromark-factory-space: 2.0.0 - micromark-util-character: 2.1.0 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 - - micromark-extension-gfm@3.0.0: - dependencies: - micromark-extension-gfm-autolink-literal: 2.0.0 - micromark-extension-gfm-footnote: 2.0.0 - micromark-extension-gfm-strikethrough: 2.0.0 - micromark-extension-gfm-table: 2.0.0 - micromark-extension-gfm-tagfilter: 2.0.0 - micromark-extension-gfm-task-list-item: 2.0.1 - micromark-util-combine-extensions: 2.0.0 - micromark-util-types: 2.0.0 - - micromark-extension-math@3.0.0: - dependencies: - '@types/katex': 0.16.7 - devlop: 1.1.0 - katex: 0.16.9 - micromark-factory-space: 2.0.0 - micromark-util-character: 2.1.0 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 - - micromark-extension-mdx-expression@3.0.0: - dependencies: - '@types/estree': 1.0.0 - devlop: 1.1.0 - micromark-factory-mdx-expression: 2.0.1 - micromark-factory-space: 2.0.0 - micromark-util-character: 2.1.0 - micromark-util-events-to-acorn: 2.0.2 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 - - micromark-extension-mdx-jsx@3.0.0: - dependencies: - '@types/acorn': 4.0.6 - '@types/estree': 1.0.0 - devlop: 1.1.0 - estree-util-is-identifier-name: 3.0.0 - micromark-factory-mdx-expression: 2.0.1 - micromark-factory-space: 2.0.0 - micromark-util-character: 2.1.0 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 - vfile-message: 4.0.2 - - micromark-extension-mdx-md@2.0.0: - dependencies: - micromark-util-types: 2.0.0 - - micromark-extension-mdxjs-esm@3.0.0: - dependencies: - '@types/estree': 1.0.0 - devlop: 1.1.0 - micromark-core-commonmark: 2.0.1 - micromark-util-character: 2.1.0 - micromark-util-events-to-acorn: 2.0.2 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 - unist-util-position-from-estree: 2.0.0 - vfile-message: 4.0.2 - - micromark-extension-mdxjs@3.0.0: - dependencies: - acorn: 8.8.1 - acorn-jsx: 5.3.2(acorn@8.8.1) - micromark-extension-mdx-expression: 3.0.0 - micromark-extension-mdx-jsx: 3.0.0 - micromark-extension-mdx-md: 2.0.0 - micromark-extension-mdxjs-esm: 3.0.0 - micromark-util-combine-extensions: 2.0.0 - micromark-util-types: 2.0.0 - - micromark-factory-destination@1.0.0: - dependencies: - micromark-util-character: 1.1.0 - micromark-util-symbol: 1.0.1 - micromark-util-types: 1.0.2 - - micromark-factory-destination@2.0.0: - dependencies: - micromark-util-character: 2.1.0 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 - - micromark-factory-label@1.0.2: - dependencies: - micromark-util-character: 1.1.0 - micromark-util-symbol: 1.0.1 - micromark-util-types: 1.0.2 - uvu: 0.5.6 - - micromark-factory-label@2.0.0: - dependencies: - devlop: 1.1.0 - micromark-util-character: 2.1.0 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 - - micromark-factory-mdx-expression@2.0.1: - dependencies: - '@types/estree': 1.0.0 - devlop: 1.1.0 - micromark-util-character: 2.1.0 - micromark-util-events-to-acorn: 2.0.2 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 - unist-util-position-from-estree: 2.0.0 - vfile-message: 4.0.2 - - micromark-factory-space@1.0.0: - dependencies: - micromark-util-character: 1.1.0 - micromark-util-types: 1.0.2 - - micromark-factory-space@2.0.0: - dependencies: - micromark-util-character: 2.1.0 - micromark-util-types: 2.0.0 - - micromark-factory-title@1.0.2: - dependencies: - micromark-factory-space: 1.0.0 - micromark-util-character: 1.1.0 - micromark-util-symbol: 1.0.1 - micromark-util-types: 1.0.2 - uvu: 0.5.6 - - micromark-factory-title@2.0.0: - dependencies: - micromark-factory-space: 2.0.0 - micromark-util-character: 2.1.0 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 - - micromark-factory-whitespace@1.0.0: - dependencies: - micromark-factory-space: 1.0.0 - micromark-util-character: 1.1.0 - micromark-util-symbol: 1.0.1 - micromark-util-types: 1.0.2 - - micromark-factory-whitespace@2.0.0: - dependencies: - micromark-factory-space: 2.0.0 - micromark-util-character: 2.1.0 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 - - micromark-util-character@1.1.0: - dependencies: - micromark-util-symbol: 1.0.1 - micromark-util-types: 1.0.2 - - micromark-util-character@2.1.0: - dependencies: - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 - - micromark-util-chunked@1.0.0: - dependencies: - micromark-util-symbol: 1.0.1 - - micromark-util-chunked@2.0.0: - dependencies: - micromark-util-symbol: 2.0.0 - - micromark-util-classify-character@1.0.0: - dependencies: - micromark-util-character: 1.1.0 - micromark-util-symbol: 1.0.1 - micromark-util-types: 1.0.2 - - micromark-util-classify-character@2.0.0: - dependencies: - micromark-util-character: 2.1.0 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 - - micromark-util-combine-extensions@1.0.0: - dependencies: - micromark-util-chunked: 1.0.0 - micromark-util-types: 1.0.2 - - micromark-util-combine-extensions@2.0.0: - dependencies: - micromark-util-chunked: 2.0.0 - micromark-util-types: 2.0.0 - - micromark-util-decode-numeric-character-reference@1.0.0: - dependencies: - micromark-util-symbol: 1.0.1 - - micromark-util-decode-numeric-character-reference@2.0.1: - dependencies: - micromark-util-symbol: 2.0.0 - - micromark-util-decode-string@1.0.2: - dependencies: - decode-named-character-reference: 1.0.2 - micromark-util-character: 1.1.0 - micromark-util-decode-numeric-character-reference: 1.0.0 - micromark-util-symbol: 1.0.1 - - micromark-util-decode-string@2.0.0: - dependencies: - decode-named-character-reference: 1.0.2 - micromark-util-character: 2.1.0 - micromark-util-decode-numeric-character-reference: 2.0.1 - micromark-util-symbol: 2.0.0 - - micromark-util-encode@1.0.1: {} - - micromark-util-encode@2.0.0: {} - - micromark-util-events-to-acorn@2.0.2: - dependencies: - '@types/acorn': 4.0.6 - '@types/estree': 1.0.0 - '@types/unist': 3.0.2 - devlop: 1.1.0 - estree-util-visit: 2.0.0 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 - vfile-message: 4.0.2 - - micromark-util-html-tag-name@1.1.0: {} - - micromark-util-html-tag-name@2.0.0: {} - - micromark-util-normalize-identifier@1.0.0: - dependencies: - micromark-util-symbol: 1.0.1 - - micromark-util-normalize-identifier@2.0.0: - dependencies: - micromark-util-symbol: 2.0.0 - - micromark-util-resolve-all@1.0.0: - dependencies: - micromark-util-types: 1.0.2 - - micromark-util-resolve-all@2.0.0: - dependencies: - micromark-util-types: 2.0.0 - - micromark-util-sanitize-uri@1.1.0: - dependencies: - micromark-util-character: 1.1.0 - micromark-util-encode: 1.0.1 - micromark-util-symbol: 1.0.1 - - micromark-util-sanitize-uri@2.0.0: - dependencies: - micromark-util-character: 2.1.0 - micromark-util-encode: 2.0.0 - micromark-util-symbol: 2.0.0 - - micromark-util-subtokenize@1.0.2: - dependencies: - micromark-util-chunked: 1.0.0 - micromark-util-symbol: 1.0.1 - micromark-util-types: 1.0.2 - uvu: 0.5.6 - - micromark-util-subtokenize@2.0.1: - dependencies: - devlop: 1.1.0 - micromark-util-chunked: 2.0.0 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 - - micromark-util-symbol@1.0.1: {} - - micromark-util-symbol@2.0.0: {} - - micromark-util-types@1.0.2: {} - - micromark-util-types@2.0.0: {} - - micromark@3.1.0: - dependencies: - '@types/debug': 4.1.7 - debug: 4.3.4 - decode-named-character-reference: 1.0.2 - micromark-core-commonmark: 1.0.6 - micromark-factory-space: 1.0.0 - micromark-util-character: 1.1.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.1 - micromark-util-normalize-identifier: 1.0.0 - micromark-util-resolve-all: 1.0.0 - micromark-util-sanitize-uri: 1.1.0 - micromark-util-subtokenize: 1.0.2 - micromark-util-symbol: 1.0.1 - micromark-util-types: 1.0.2 - uvu: 0.5.6 - transitivePeerDependencies: - - supports-color - - micromark@4.0.0: - dependencies: - '@types/debug': 4.1.7 - debug: 4.3.4 - decode-named-character-reference: 1.0.2 - devlop: 1.1.0 - micromark-core-commonmark: 2.0.1 - micromark-factory-space: 2.0.0 - micromark-util-character: 2.1.0 - micromark-util-chunked: 2.0.0 - micromark-util-combine-extensions: 2.0.0 - micromark-util-decode-numeric-character-reference: 2.0.1 - micromark-util-encode: 2.0.0 - micromark-util-normalize-identifier: 2.0.0 - micromark-util-resolve-all: 2.0.0 - micromark-util-sanitize-uri: 2.0.0 - micromark-util-subtokenize: 2.0.1 - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 - transitivePeerDependencies: - - supports-color - - mj-context-menu@0.6.1: {} - - mri@1.2.0: {} - - ms@2.1.2: {} - - nanoid@3.3.7: {} - - next-themes@0.3.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0): - dependencies: - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - - next@14.1.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0): - dependencies: - '@next/env': 14.1.1 - '@swc/helpers': 0.5.2 - busboy: 1.6.0 - caniuse-lite: 1.0.30001591 - graceful-fs: 4.2.11 - postcss: 8.4.31 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - styled-jsx: 5.1.1(react@18.2.0) - optionalDependencies: - '@next/swc-darwin-arm64': 14.1.1 - '@next/swc-darwin-x64': 14.1.1 - '@next/swc-linux-arm64-gnu': 14.1.1 - '@next/swc-linux-arm64-musl': 14.1.1 - '@next/swc-linux-x64-gnu': 14.1.1 - '@next/swc-linux-x64-musl': 14.1.1 - '@next/swc-win32-arm64-msvc': 14.1.1 - '@next/swc-win32-ia32-msvc': 14.1.1 - '@next/swc-win32-x64-msvc': 14.1.1 - transitivePeerDependencies: - - '@babel/core' - - babel-plugin-macros - - nextra-theme-docs@3.0.0-alpha.24(next@14.1.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(nextra@3.0.0-alpha.24(@types/react@18.0.26)(next@14.1.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.3.3))(react-dom@18.2.0(react@18.2.0))(react@18.2.0): - dependencies: - '@headlessui/react': 1.7.18(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - '@popperjs/core': 2.11.8 - clsx: 2.1.0 - escape-string-regexp: 5.0.0 - flexsearch: 0.7.43 - focus-visible: 5.2.0 - intersection-observer: 0.12.2 - next: 14.1.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - next-themes: 0.3.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - nextra: 3.0.0-alpha.24(@types/react@18.0.26)(next@14.1.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.3.3) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - scroll-into-view-if-needed: 3.1.0 - zod: 3.22.4 - - nextra@3.0.0-alpha.24(@types/react@18.0.26)(next@14.1.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.3.3): - dependencies: - '@headlessui/react': 1.7.18(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - '@mdx-js/mdx': 3.0.1 - '@mdx-js/react': 3.0.1(@types/react@18.0.26)(react@18.2.0) - '@napi-rs/simple-git': 0.1.16 - '@shikijs/twoslash': 1.6.1(typescript@5.3.3) - '@theguild/remark-mermaid': 0.0.5(react@18.2.0) - '@theguild/remark-npm2yarn': 0.3.0 - better-react-mathjax: 2.0.3(react@18.2.0) - clsx: 2.1.0 - estree-util-to-js: 2.0.0 - estree-util-value-to-estree: 3.1.1 - github-slugger: 2.0.0 - graceful-fs: 4.2.11 - gray-matter: 4.0.3 - hast-util-to-estree: 3.1.0 - katex: 0.16.9 - next: 14.1.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - p-limit: 4.0.0 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - rehype-katex: 7.0.0 - rehype-pretty-code: 0.13.0(shiki@1.6.1) - rehype-raw: 7.0.0 - remark-frontmatter: 5.0.0 - remark-gfm: 4.0.0 - remark-math: 6.0.0 - remark-reading-time: 2.0.1 - remark-smartypants: 2.1.0 - shiki: 1.6.1 - slash: 5.1.0 - title: 3.5.3 - unist-util-remove: 4.0.0 - unist-util-visit: 5.0.0 - yaml: 2.4.2 - zod: 3.22.4 - zod-validation-error: 1.5.0(zod@3.22.4) - transitivePeerDependencies: - - '@types/react' - - supports-color - - typescript - - nlcst-to-string@3.1.1: - dependencies: - '@types/nlcst': 1.0.4 - - non-layered-tidy-tree-layout@2.0.2: {} - - npm-run-path@2.0.2: - dependencies: - path-key: 2.0.1 - - npm-to-yarn@2.2.1: {} - - p-finally@1.0.0: {} - - p-limit@4.0.0: - dependencies: - yocto-queue: 1.0.0 - - parse-entities@4.0.0: - dependencies: - '@types/unist': 2.0.6 - character-entities: 2.0.2 - character-entities-legacy: 3.0.0 - character-reference-invalid: 2.0.1 - decode-named-character-reference: 1.0.2 - is-alphanumerical: 2.0.1 - is-decimal: 2.0.1 - is-hexadecimal: 2.0.1 - - parse-latin@5.0.1: - dependencies: - nlcst-to-string: 3.1.1 - unist-util-modify-children: 3.1.1 - unist-util-visit-children: 2.0.2 - - parse-numeric-range@1.3.0: {} - - parse5@7.1.2: - dependencies: - entities: 4.5.0 - - path-key@2.0.1: {} - - periscopic@3.0.4: - dependencies: - estree-walker: 3.0.1 - is-reference: 3.0.0 - - picocolors@1.0.0: {} - - postcss@8.4.31: - dependencies: - nanoid: 3.3.7 - picocolors: 1.0.0 - source-map-js: 1.0.2 - - property-information@6.2.0: {} - - pseudomap@1.0.2: {} - - react-dom@18.2.0(react@18.2.0): - dependencies: - loose-envify: 1.4.0 - react: 18.2.0 - scheduler: 0.23.0 - - react@18.2.0: - dependencies: - loose-envify: 1.4.0 - - reading-time@1.5.0: {} - - rehype-katex@7.0.0: - dependencies: - '@types/hast': 3.0.4 - '@types/katex': 0.16.7 - hast-util-from-html-isomorphic: 2.0.0 - hast-util-to-text: 4.0.0 - katex: 0.16.9 - unist-util-visit-parents: 6.0.1 - vfile: 6.0.1 - - rehype-parse@9.0.0: - dependencies: - '@types/hast': 3.0.4 - hast-util-from-html: 2.0.1 - unified: 11.0.4 - - rehype-pretty-code@0.13.0(shiki@1.6.1): - dependencies: - '@types/hast': 3.0.4 - hast-util-to-string: 3.0.0 - parse-numeric-range: 1.3.0 - rehype-parse: 9.0.0 - shiki: 1.6.1 - unified: 11.0.4 - unist-util-visit: 5.0.0 - - rehype-raw@7.0.0: - dependencies: - '@types/hast': 3.0.4 - hast-util-raw: 9.0.2 - vfile: 6.0.1 - - remark-frontmatter@5.0.0: - dependencies: - '@types/mdast': 4.0.3 - mdast-util-frontmatter: 2.0.1 - micromark-extension-frontmatter: 2.0.0 - unified: 11.0.4 - transitivePeerDependencies: - - supports-color - - remark-gfm@4.0.0: - dependencies: - '@types/mdast': 4.0.3 - mdast-util-gfm: 3.0.0 - micromark-extension-gfm: 3.0.0 - remark-parse: 11.0.0 - remark-stringify: 11.0.0 - unified: 11.0.4 - transitivePeerDependencies: - - supports-color - - remark-math@6.0.0: - dependencies: - '@types/mdast': 4.0.3 - mdast-util-math: 3.0.0 - micromark-extension-math: 3.0.0 - unified: 11.0.4 - transitivePeerDependencies: - - supports-color - - remark-mdx@3.0.1: - dependencies: - mdast-util-mdx: 3.0.0 - micromark-extension-mdxjs: 3.0.0 - transitivePeerDependencies: - - supports-color - - remark-parse@11.0.0: - dependencies: - '@types/mdast': 4.0.3 - mdast-util-from-markdown: 2.0.1 - micromark-util-types: 2.0.0 - unified: 11.0.4 - transitivePeerDependencies: - - supports-color - - remark-reading-time@2.0.1: - dependencies: - estree-util-is-identifier-name: 2.0.1 - estree-util-value-to-estree: 1.3.0 - reading-time: 1.5.0 - unist-util-visit: 3.1.0 - - remark-rehype@11.1.0: - dependencies: - '@types/hast': 3.0.4 - '@types/mdast': 4.0.3 - mdast-util-to-hast: 13.1.0 - unified: 11.0.4 - vfile: 6.0.1 - - remark-smartypants@2.1.0: - dependencies: - retext: 8.1.0 - retext-smartypants: 5.2.0 - unist-util-visit: 5.0.0 - - remark-stringify@11.0.0: - dependencies: - '@types/mdast': 4.0.3 - mdast-util-to-markdown: 2.1.0 - unified: 11.0.4 - - retext-latin@3.1.0: - dependencies: - '@types/nlcst': 1.0.4 - parse-latin: 5.0.1 - unherit: 3.0.1 - unified: 10.1.2 - - retext-smartypants@5.2.0: - dependencies: - '@types/nlcst': 1.0.4 - nlcst-to-string: 3.1.1 - unified: 10.1.2 - unist-util-visit: 4.1.1 - - retext-stringify@3.1.0: - dependencies: - '@types/nlcst': 1.0.4 - nlcst-to-string: 3.1.1 - unified: 10.1.2 - - retext@8.1.0: - dependencies: - '@types/nlcst': 1.0.4 - retext-latin: 3.1.0 - retext-stringify: 3.1.0 - unified: 10.1.2 - - robust-predicates@3.0.2: {} - - rw@1.3.3: {} - - sade@1.8.1: - dependencies: - mri: 1.2.0 - - safer-buffer@2.1.2: {} - - scheduler@0.23.0: - dependencies: - loose-envify: 1.4.0 - - scroll-into-view-if-needed@3.1.0: - dependencies: - compute-scroll-into-view: 3.1.0 - - section-matter@1.0.0: - dependencies: - extend-shallow: 2.0.1 - kind-of: 6.0.3 - - shebang-command@1.2.0: - dependencies: - shebang-regex: 1.0.0 - - shebang-regex@1.0.0: {} - - shiki@1.6.1: - dependencies: - '@shikijs/core': 1.6.1 - - signal-exit@3.0.7: {} - - slash@5.1.0: {} - - source-map-js@1.0.2: {} - - source-map@0.7.4: {} - - space-separated-tokens@2.0.2: {} - - speech-rule-engine@4.0.7: - dependencies: - commander: 9.2.0 - wicked-good-xpath: 1.3.0 - xmldom-sre: 0.1.31 - - sprintf-js@1.0.3: {} - - streamsearch@1.1.0: {} - - stringify-entities@4.0.3: - dependencies: - character-entities-html4: 2.1.0 - character-entities-legacy: 3.0.0 - - strip-bom-string@1.0.0: {} - - strip-eof@1.0.0: {} - - style-to-object@0.4.4: - dependencies: - inline-style-parser: 0.1.1 - - style-to-object@1.0.6: - dependencies: - inline-style-parser: 0.2.3 - - styled-jsx@5.1.1(react@18.2.0): - dependencies: - client-only: 0.0.1 - react: 18.2.0 - - stylis@4.3.1: {} - - supports-color@4.5.0: - dependencies: - has-flag: 2.0.0 - - title@3.5.3: - dependencies: - arg: 1.0.0 - chalk: 2.3.0 - clipboardy: 1.2.2 - titleize: 1.0.0 - - titleize@1.0.0: {} - - trim-lines@3.0.1: {} - - trough@2.1.0: {} - - ts-dedent@2.2.0: {} - - tslib@2.4.1: {} - - twoslash-protocol@0.2.6: {} - - twoslash@0.2.6(typescript@5.3.3): - dependencies: - '@typescript/vfs': 1.5.0 - twoslash-protocol: 0.2.6 - typescript: 5.3.3 - transitivePeerDependencies: - - supports-color - - typescript@5.3.3: {} - - undici-types@5.26.5: {} - - unherit@3.0.1: {} - - unified@10.1.2: - dependencies: - '@types/unist': 2.0.6 - bail: 2.0.2 - extend: 3.0.2 - is-buffer: 2.0.5 - is-plain-obj: 4.1.0 - trough: 2.1.0 - vfile: 5.3.6 - - unified@11.0.4: - dependencies: - '@types/unist': 3.0.2 - bail: 2.0.2 - devlop: 1.1.0 - extend: 3.0.2 - is-plain-obj: 4.1.0 - trough: 2.1.0 - vfile: 6.0.1 - - unist-util-find-after@5.0.0: - dependencies: - '@types/unist': 3.0.2 - unist-util-is: 6.0.0 - - unist-util-is@5.1.1: {} - - unist-util-is@6.0.0: - dependencies: - '@types/unist': 3.0.2 - - unist-util-modify-children@3.1.1: - dependencies: - '@types/unist': 2.0.6 - array-iterate: 2.0.1 - - unist-util-position-from-estree@2.0.0: - dependencies: - '@types/unist': 3.0.2 - - unist-util-position@5.0.0: - dependencies: - '@types/unist': 3.0.2 - - unist-util-remove-position@5.0.0: - dependencies: - '@types/unist': 3.0.2 - unist-util-visit: 5.0.0 - - unist-util-remove@4.0.0: - dependencies: - '@types/unist': 3.0.2 - unist-util-is: 6.0.0 - unist-util-visit-parents: 6.0.1 - - unist-util-stringify-position@3.0.2: - dependencies: - '@types/unist': 2.0.6 - - unist-util-stringify-position@4.0.0: - dependencies: - '@types/unist': 3.0.2 - - unist-util-visit-children@2.0.2: - dependencies: - '@types/unist': 2.0.6 - - unist-util-visit-parents@4.1.1: - dependencies: - '@types/unist': 2.0.6 - unist-util-is: 5.1.1 - - unist-util-visit-parents@5.1.1: - dependencies: - '@types/unist': 2.0.6 - unist-util-is: 5.1.1 - - unist-util-visit-parents@6.0.1: - dependencies: - '@types/unist': 3.0.2 - unist-util-is: 6.0.0 - - unist-util-visit@3.1.0: - dependencies: - '@types/unist': 2.0.6 - unist-util-is: 5.1.1 - unist-util-visit-parents: 4.1.1 - - unist-util-visit@4.1.1: - dependencies: - '@types/unist': 2.0.6 - unist-util-is: 5.1.1 - unist-util-visit-parents: 5.1.1 - - unist-util-visit@5.0.0: - dependencies: - '@types/unist': 3.0.2 - unist-util-is: 6.0.0 - unist-util-visit-parents: 6.0.1 - - uuid@9.0.1: {} - - uvu@0.5.6: - dependencies: - dequal: 2.0.3 - diff: 5.1.0 - kleur: 4.1.5 - sade: 1.8.1 - - vfile-location@5.0.2: - dependencies: - '@types/unist': 3.0.2 - vfile: 6.0.1 - - vfile-message@3.1.3: - dependencies: - '@types/unist': 2.0.6 - unist-util-stringify-position: 3.0.2 - - vfile-message@4.0.2: - dependencies: - '@types/unist': 3.0.2 - unist-util-stringify-position: 4.0.0 - - vfile@5.3.6: - dependencies: - '@types/unist': 2.0.6 - is-buffer: 2.0.5 - unist-util-stringify-position: 3.0.2 - vfile-message: 3.1.3 - - vfile@6.0.1: - dependencies: - '@types/unist': 3.0.2 - unist-util-stringify-position: 4.0.0 - vfile-message: 4.0.2 - - web-namespaces@2.0.1: {} - - web-worker@1.3.0: {} - - which@1.3.1: - dependencies: - isexe: 2.0.0 - - wicked-good-xpath@1.3.0: {} - - xmldom-sre@0.1.31: {} - - yallist@2.1.2: {} - - yaml@2.4.2: {} - - yocto-queue@1.0.0: {} - - zod-validation-error@1.5.0(zod@3.22.4): - dependencies: - zod: 3.22.4 - - zod@3.22.4: {} - - zwitch@2.0.4: {} diff --git a/src/stale/hyperglass/docs/public/hyperglass-dark.svg b/src/stale/hyperglass/docs/public/hyperglass-dark.svg deleted file mode 100644 index b93080f..0000000 --- a/src/stale/hyperglass/docs/public/hyperglass-dark.svg +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/src/stale/hyperglass/docs/public/hyperglass-icon-dark.svg b/src/stale/hyperglass/docs/public/hyperglass-icon-dark.svg deleted file mode 100644 index ea9b648..0000000 --- a/src/stale/hyperglass/docs/public/hyperglass-icon-dark.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/stale/hyperglass/docs/public/hyperglass-icon-light.svg b/src/stale/hyperglass/docs/public/hyperglass-icon-light.svg deleted file mode 100644 index 7dfbb56..0000000 --- a/src/stale/hyperglass/docs/public/hyperglass-icon-light.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/stale/hyperglass/docs/public/hyperglass-light.svg b/src/stale/hyperglass/docs/public/hyperglass-light.svg deleted file mode 100644 index b2bb038..0000000 --- a/src/stale/hyperglass/docs/public/hyperglass-light.svg +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/src/stale/hyperglass/docs/public/hyperglass.svg b/src/stale/hyperglass/docs/public/hyperglass.svg deleted file mode 100644 index bcfd80d..0000000 --- a/src/stale/hyperglass/docs/public/hyperglass.svg +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/src/stale/hyperglass/docs/public/img/android-chrome-144x144.png b/src/stale/hyperglass/docs/public/img/android-chrome-144x144.png deleted file mode 100644 index 1b6adf5..0000000 Binary files a/src/stale/hyperglass/docs/public/img/android-chrome-144x144.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/android-chrome-192x192.png b/src/stale/hyperglass/docs/public/img/android-chrome-192x192.png deleted file mode 100644 index 6719465..0000000 Binary files a/src/stale/hyperglass/docs/public/img/android-chrome-192x192.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/android-chrome-256x256.png b/src/stale/hyperglass/docs/public/img/android-chrome-256x256.png deleted file mode 100644 index b79802f..0000000 Binary files a/src/stale/hyperglass/docs/public/img/android-chrome-256x256.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/android-chrome-36x36.png b/src/stale/hyperglass/docs/public/img/android-chrome-36x36.png deleted file mode 100644 index bc7f529..0000000 Binary files a/src/stale/hyperglass/docs/public/img/android-chrome-36x36.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/android-chrome-384x384.png b/src/stale/hyperglass/docs/public/img/android-chrome-384x384.png deleted file mode 100644 index 03175a4..0000000 Binary files a/src/stale/hyperglass/docs/public/img/android-chrome-384x384.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/android-chrome-48x48.png b/src/stale/hyperglass/docs/public/img/android-chrome-48x48.png deleted file mode 100644 index 574f207..0000000 Binary files a/src/stale/hyperglass/docs/public/img/android-chrome-48x48.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/android-chrome-512x512.png b/src/stale/hyperglass/docs/public/img/android-chrome-512x512.png deleted file mode 100644 index d906d9f..0000000 Binary files a/src/stale/hyperglass/docs/public/img/android-chrome-512x512.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/android-chrome-72x72.png b/src/stale/hyperglass/docs/public/img/android-chrome-72x72.png deleted file mode 100644 index 8fd8da4..0000000 Binary files a/src/stale/hyperglass/docs/public/img/android-chrome-72x72.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/android-chrome-96x96.png b/src/stale/hyperglass/docs/public/img/android-chrome-96x96.png deleted file mode 100644 index 83c62fa..0000000 Binary files a/src/stale/hyperglass/docs/public/img/android-chrome-96x96.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/apple-touch-icon-1024x1024.png b/src/stale/hyperglass/docs/public/img/apple-touch-icon-1024x1024.png deleted file mode 100644 index 1cc2ce0..0000000 Binary files a/src/stale/hyperglass/docs/public/img/apple-touch-icon-1024x1024.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/apple-touch-icon-114x114.png b/src/stale/hyperglass/docs/public/img/apple-touch-icon-114x114.png deleted file mode 100644 index 3ba48ae..0000000 Binary files a/src/stale/hyperglass/docs/public/img/apple-touch-icon-114x114.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/apple-touch-icon-120x120.png b/src/stale/hyperglass/docs/public/img/apple-touch-icon-120x120.png deleted file mode 100644 index c326a20..0000000 Binary files a/src/stale/hyperglass/docs/public/img/apple-touch-icon-120x120.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/apple-touch-icon-144x144.png b/src/stale/hyperglass/docs/public/img/apple-touch-icon-144x144.png deleted file mode 100644 index ca328b7..0000000 Binary files a/src/stale/hyperglass/docs/public/img/apple-touch-icon-144x144.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/apple-touch-icon-152x152.png b/src/stale/hyperglass/docs/public/img/apple-touch-icon-152x152.png deleted file mode 100644 index 8421ceb..0000000 Binary files a/src/stale/hyperglass/docs/public/img/apple-touch-icon-152x152.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/apple-touch-icon-167x167.png b/src/stale/hyperglass/docs/public/img/apple-touch-icon-167x167.png deleted file mode 100644 index 2e8b2c0..0000000 Binary files a/src/stale/hyperglass/docs/public/img/apple-touch-icon-167x167.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/apple-touch-icon-180x180.png b/src/stale/hyperglass/docs/public/img/apple-touch-icon-180x180.png deleted file mode 100644 index 7ce8953..0000000 Binary files a/src/stale/hyperglass/docs/public/img/apple-touch-icon-180x180.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/apple-touch-icon-57x57.png b/src/stale/hyperglass/docs/public/img/apple-touch-icon-57x57.png deleted file mode 100644 index 58910f5..0000000 Binary files a/src/stale/hyperglass/docs/public/img/apple-touch-icon-57x57.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/apple-touch-icon-60x60.png b/src/stale/hyperglass/docs/public/img/apple-touch-icon-60x60.png deleted file mode 100644 index 75cbf7c..0000000 Binary files a/src/stale/hyperglass/docs/public/img/apple-touch-icon-60x60.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/apple-touch-icon-72x72.png b/src/stale/hyperglass/docs/public/img/apple-touch-icon-72x72.png deleted file mode 100644 index e310a90..0000000 Binary files a/src/stale/hyperglass/docs/public/img/apple-touch-icon-72x72.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/apple-touch-icon-76x76.png b/src/stale/hyperglass/docs/public/img/apple-touch-icon-76x76.png deleted file mode 100644 index 41ac8e8..0000000 Binary files a/src/stale/hyperglass/docs/public/img/apple-touch-icon-76x76.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/apple-touch-icon-precomposed.png b/src/stale/hyperglass/docs/public/img/apple-touch-icon-precomposed.png deleted file mode 100644 index 7ce8953..0000000 Binary files a/src/stale/hyperglass/docs/public/img/apple-touch-icon-precomposed.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/apple-touch-icon.png b/src/stale/hyperglass/docs/public/img/apple-touch-icon.png deleted file mode 100644 index 7ce8953..0000000 Binary files a/src/stale/hyperglass/docs/public/img/apple-touch-icon.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-1125x2436.png b/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-1125x2436.png deleted file mode 100644 index 648279b..0000000 Binary files a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-1125x2436.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-1136x640.png b/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-1136x640.png deleted file mode 100644 index fae39ea..0000000 Binary files a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-1136x640.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-1242x2208.png b/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-1242x2208.png deleted file mode 100644 index ecd5291..0000000 Binary files a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-1242x2208.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-1242x2688.png b/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-1242x2688.png deleted file mode 100644 index 8fa11c1..0000000 Binary files a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-1242x2688.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-1334x750.png b/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-1334x750.png deleted file mode 100644 index 08c1a7e..0000000 Binary files a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-1334x750.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-1536x2048.png b/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-1536x2048.png deleted file mode 100644 index 423d4cc..0000000 Binary files a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-1536x2048.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-1620x2160.png b/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-1620x2160.png deleted file mode 100644 index 4cf396c..0000000 Binary files a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-1620x2160.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-1668x2224.png b/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-1668x2224.png deleted file mode 100644 index 2add1c5..0000000 Binary files a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-1668x2224.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-1668x2388.png b/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-1668x2388.png deleted file mode 100644 index 5ffbf5a..0000000 Binary files a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-1668x2388.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-1792x828.png b/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-1792x828.png deleted file mode 100644 index 3e359af..0000000 Binary files a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-1792x828.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-2048x1536.png b/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-2048x1536.png deleted file mode 100644 index 1e11671..0000000 Binary files a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-2048x1536.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-2048x2732.png b/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-2048x2732.png deleted file mode 100644 index 7218956..0000000 Binary files a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-2048x2732.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-2160x1620.png b/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-2160x1620.png deleted file mode 100644 index b8167a1..0000000 Binary files a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-2160x1620.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-2208x1242.png b/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-2208x1242.png deleted file mode 100644 index 73b0ec4..0000000 Binary files a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-2208x1242.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-2224x1668.png b/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-2224x1668.png deleted file mode 100644 index 42adbbf..0000000 Binary files a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-2224x1668.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-2388x1668.png b/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-2388x1668.png deleted file mode 100644 index 1272138..0000000 Binary files a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-2388x1668.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-2436x1125.png b/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-2436x1125.png deleted file mode 100644 index b431124..0000000 Binary files a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-2436x1125.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-2688x1242.png b/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-2688x1242.png deleted file mode 100644 index 2e45338..0000000 Binary files a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-2688x1242.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-2732x2048.png b/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-2732x2048.png deleted file mode 100644 index 9a44a06..0000000 Binary files a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-2732x2048.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-640x1136.png b/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-640x1136.png deleted file mode 100644 index 26cfb6f..0000000 Binary files a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-640x1136.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-750x1334.png b/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-750x1334.png deleted file mode 100644 index 50fb34b..0000000 Binary files a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-750x1334.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-828x1792.png b/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-828x1792.png deleted file mode 100644 index 75d8699..0000000 Binary files a/src/stale/hyperglass/docs/public/img/apple-touch-startup-image-828x1792.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/browserconfig.xml b/src/stale/hyperglass/docs/public/img/browserconfig.xml deleted file mode 100644 index 6a446a9..0000000 --- a/src/stale/hyperglass/docs/public/img/browserconfig.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - #f5f6f7 - - - - - - diff --git a/src/stale/hyperglass/docs/public/img/coast-228x228.png b/src/stale/hyperglass/docs/public/img/coast-228x228.png deleted file mode 100644 index 216825f..0000000 Binary files a/src/stale/hyperglass/docs/public/img/coast-228x228.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/favicon-16x16.png b/src/stale/hyperglass/docs/public/img/favicon-16x16.png deleted file mode 100644 index f742b4a..0000000 Binary files a/src/stale/hyperglass/docs/public/img/favicon-16x16.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/favicon-32x32.png b/src/stale/hyperglass/docs/public/img/favicon-32x32.png deleted file mode 100644 index a1c67cc..0000000 Binary files a/src/stale/hyperglass/docs/public/img/favicon-32x32.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/favicon-48x48.png b/src/stale/hyperglass/docs/public/img/favicon-48x48.png deleted file mode 100644 index 574f207..0000000 Binary files a/src/stale/hyperglass/docs/public/img/favicon-48x48.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/favicon.ico b/src/stale/hyperglass/docs/public/img/favicon.ico deleted file mode 100644 index ada0c90..0000000 Binary files a/src/stale/hyperglass/docs/public/img/favicon.ico and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/firefox_app_128x128.png b/src/stale/hyperglass/docs/public/img/firefox_app_128x128.png deleted file mode 100644 index d155a12..0000000 Binary files a/src/stale/hyperglass/docs/public/img/firefox_app_128x128.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/firefox_app_512x512.png b/src/stale/hyperglass/docs/public/img/firefox_app_512x512.png deleted file mode 100644 index 00e4a5c..0000000 Binary files a/src/stale/hyperglass/docs/public/img/firefox_app_512x512.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/firefox_app_60x60.png b/src/stale/hyperglass/docs/public/img/firefox_app_60x60.png deleted file mode 100644 index ae76a46..0000000 Binary files a/src/stale/hyperglass/docs/public/img/firefox_app_60x60.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/icon.svg b/src/stale/hyperglass/docs/public/img/icon.svg deleted file mode 100644 index ea9b648..0000000 --- a/src/stale/hyperglass/docs/public/img/icon.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/stale/hyperglass/docs/public/img/manifest.json b/src/stale/hyperglass/docs/public/img/manifest.json deleted file mode 100644 index 8b40b48..0000000 --- a/src/stale/hyperglass/docs/public/img/manifest.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "name": "dev hyperglass", - "short_name": "dev hyperglass", - "description": "Beloved Hyperglass User Network Looking Glass", - "dir": "auto", - "lang": "en-US", - "display": "standalone", - "orientation": "any", - "scope": "/", - "start_url": "/?homescreen=1", - "background_color": "#f5f6f7", - "theme_color": "#118ab2", - "icons": [ - { - "src": "/images/favicons/android-chrome-36x36.png", - "sizes": "36x36", - "type": "image/png" - }, - { - "src": "/images/favicons/android-chrome-48x48.png", - "sizes": "48x48", - "type": "image/png" - }, - { - "src": "/images/favicons/android-chrome-72x72.png", - "sizes": "72x72", - "type": "image/png" - }, - { - "src": "/images/favicons/android-chrome-96x96.png", - "sizes": "96x96", - "type": "image/png" - }, - { - "src": "/images/favicons/android-chrome-144x144.png", - "sizes": "144x144", - "type": "image/png" - }, - { - "src": "/images/favicons/android-chrome-192x192.png", - "sizes": "192x192", - "type": "image/png" - }, - { - "src": "/images/favicons/android-chrome-256x256.png", - "sizes": "256x256", - "type": "image/png" - }, - { - "src": "/images/favicons/android-chrome-384x384.png", - "sizes": "384x384", - "type": "image/png" - }, - { - "src": "/images/favicons/android-chrome-512x512.png", - "sizes": "512x512", - "type": "image/png" - } - ] -} \ No newline at end of file diff --git a/src/stale/hyperglass/docs/public/img/manifest.webapp b/src/stale/hyperglass/docs/public/img/manifest.webapp deleted file mode 100644 index 7e94553..0000000 --- a/src/stale/hyperglass/docs/public/img/manifest.webapp +++ /dev/null @@ -1,14 +0,0 @@ -{ - "version": "1.0", - "name": "dev hyperglass", - "description": "Beloved Hyperglass User Network Looking Glass", - "icons": { - "60": "/images/favicons/firefox_app_60x60.png", - "128": "/images/favicons/firefox_app_128x128.png", - "512": "/images/favicons/firefox_app_512x512.png" - }, - "developer": { - "name": null, - "url": null - } -} \ No newline at end of file diff --git a/src/stale/hyperglass/docs/public/img/mstile-144x144.png b/src/stale/hyperglass/docs/public/img/mstile-144x144.png deleted file mode 100644 index 1b6adf5..0000000 Binary files a/src/stale/hyperglass/docs/public/img/mstile-144x144.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/mstile-150x150.png b/src/stale/hyperglass/docs/public/img/mstile-150x150.png deleted file mode 100644 index 0a11b4f..0000000 Binary files a/src/stale/hyperglass/docs/public/img/mstile-150x150.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/mstile-310x150.png b/src/stale/hyperglass/docs/public/img/mstile-310x150.png deleted file mode 100644 index 13a0c9e..0000000 Binary files a/src/stale/hyperglass/docs/public/img/mstile-310x150.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/mstile-310x310.png b/src/stale/hyperglass/docs/public/img/mstile-310x310.png deleted file mode 100644 index ce0fbfe..0000000 Binary files a/src/stale/hyperglass/docs/public/img/mstile-310x310.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/mstile-70x70.png b/src/stale/hyperglass/docs/public/img/mstile-70x70.png deleted file mode 100644 index cd0fa26..0000000 Binary files a/src/stale/hyperglass/docs/public/img/mstile-70x70.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/undraw_docusaurus_mountain.svg b/src/stale/hyperglass/docs/public/img/undraw_docusaurus_mountain.svg deleted file mode 100755 index 431cef2..0000000 --- a/src/stale/hyperglass/docs/public/img/undraw_docusaurus_mountain.svg +++ /dev/null @@ -1,170 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/stale/hyperglass/docs/public/img/undraw_docusaurus_react.svg b/src/stale/hyperglass/docs/public/img/undraw_docusaurus_react.svg deleted file mode 100755 index e417050..0000000 --- a/src/stale/hyperglass/docs/public/img/undraw_docusaurus_react.svg +++ /dev/null @@ -1,169 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/stale/hyperglass/docs/public/img/undraw_docusaurus_tree.svg b/src/stale/hyperglass/docs/public/img/undraw_docusaurus_tree.svg deleted file mode 100755 index a05cc03..0000000 --- a/src/stale/hyperglass/docs/public/img/undraw_docusaurus_tree.svg +++ /dev/null @@ -1 +0,0 @@ -docu_tree \ No newline at end of file diff --git a/src/stale/hyperglass/docs/public/img/yandex-browser-50x50.png b/src/stale/hyperglass/docs/public/img/yandex-browser-50x50.png deleted file mode 100644 index cf98b52..0000000 Binary files a/src/stale/hyperglass/docs/public/img/yandex-browser-50x50.png and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/img/yandex-browser-manifest.json b/src/stale/hyperglass/docs/public/img/yandex-browser-manifest.json deleted file mode 100644 index 1fbf8df..0000000 --- a/src/stale/hyperglass/docs/public/img/yandex-browser-manifest.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "version": "1.0", - "api_version": 1, - "layout": { - "logo": "/images/favicons/yandex-browser-50x50.png", - "color": "#f5f6f7", - "show_title": true - } -} \ No newline at end of file diff --git a/src/stale/hyperglass/docs/public/opengraph.jpg b/src/stale/hyperglass/docs/public/opengraph.jpg deleted file mode 100644 index 3d621d9..0000000 Binary files a/src/stale/hyperglass/docs/public/opengraph.jpg and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/robots.txt b/src/stale/hyperglass/docs/public/robots.txt deleted file mode 100644 index 296c638..0000000 --- a/src/stale/hyperglass/docs/public/robots.txt +++ /dev/null @@ -1,3 +0,0 @@ -User-agent: * -Disallow: /*__* -Sitemap: https://hyperglass.dev/sitemap.xml \ No newline at end of file diff --git a/src/stale/hyperglass/docs/public/screenshots/screenshot-favicons.jpg b/src/stale/hyperglass/docs/public/screenshots/screenshot-favicons.jpg deleted file mode 100644 index 4795652..0000000 Binary files a/src/stale/hyperglass/docs/public/screenshots/screenshot-favicons.jpg and /dev/null differ diff --git a/src/stale/hyperglass/docs/public/traceroute_nanog.pdf b/src/stale/hyperglass/docs/public/traceroute_nanog.pdf deleted file mode 100644 index e9ca8b1..0000000 Binary files a/src/stale/hyperglass/docs/public/traceroute_nanog.pdf and /dev/null differ diff --git a/src/stale/hyperglass/docs/theme.config.tsx b/src/stale/hyperglass/docs/theme.config.tsx deleted file mode 100644 index 97d17d9..0000000 --- a/src/stale/hyperglass/docs/theme.config.tsx +++ /dev/null @@ -1,144 +0,0 @@ -import { useRouter } from "next/router"; -import { type DocsThemeConfig, useConfig } from "nextra-theme-docs"; -import "nextra-theme-docs/style.css"; -import faviconFormats from "./favicon-formats"; -import styles from "./global.module.css"; - -const NO_INDEX_FOLLOW = process.env.CF_PAGES_BRANCH !== "main"; - -const config: DocsThemeConfig = { - logo: ( - - - hyperglass - - - - - - - - - - - - - - - - - - - - - - ), - head: () => { - const { asPath, locale, defaultLocale } = useRouter(); - const { frontMatter } = useConfig(); - const url = `https://hyperglass.dev${ - defaultLocale === locale ? asPath : `/${locale}${asPath}` - }`; - let title = frontMatter.title || "hyperglass"; - if (title !== "hyperglass") { - title = `${title} | hyperglass`; - } - const description = frontMatter.description || "hyperglass Documentation"; - const index = NO_INDEX_FOLLOW ? "noindex, nofollow" : "index, follow"; - const favicons = faviconFormats.map((fmt) => { - const { image_format, dimensions, prefix, rel } = fmt; - const [w, h] = dimensions; - const href = `/img/${prefix}-${w}x${h}.${image_format}`; - return { rel: rel ?? "", href, type: `image/${image_format}` }; - }); - - return ( - - {title} - - - - - - - - - - - - - - {favicons.map((props) => ( - - ))} - - ); - }, - docsRepositoryBase: "https://github.com/thatmattlove/hyperglass/tree/main/docs", - banner: { - dismissible: true, - content: "🎉 hyperglass 2.0 is here! This documentation is still in development, though.", - }, - feedback: { content: null }, - footer: { content: `© ${new Date().getFullYear()} hyperglass` }, - editLink: { component: null }, - chat: { - link: "https://netdev.chat/", - icon: ( - - NetDev Chat - - - ), - }, - project: { - link: "https://github.com/thatmattlove/hyperglass", - }, -}; - -export default config; diff --git a/src/stale/hyperglass/docs/tsconfig.json b/src/stale/hyperglass/docs/tsconfig.json deleted file mode 100644 index 4fe9021..0000000 --- a/src/stale/hyperglass/docs/tsconfig.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "compilerOptions": { - "target": "ESNext", - "module": "esnext", - "downlevelIteration": true, - "strict": true, - "baseUrl": ".", - "esModuleInterop": true, - "skipLibCheck": true, - "forceConsistentCasingInFileNames": true, - "lib": ["dom", "dom.iterable", "esnext"], - "allowJs": true, - "noEmit": true, - "moduleResolution": "node", - "resolveJsonModule": true, - "isolatedModules": true, - "jsx": "preserve", - "incremental": true, - "paths": { - "~/*": ["./*"] - } - }, - - "exclude": ["node_modules", ".next"], - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "next.config.mjs"] -} diff --git a/src/stale/hyperglass/hyperglass/ui/.eslintignore-delete b/src/stale/hyperglass/hyperglass/ui/.eslintignore-delete deleted file mode 100644 index e06f250..0000000 --- a/src/stale/hyperglass/hyperglass/ui/.eslintignore-delete +++ /dev/null @@ -1,5 +0,0 @@ -node_modules -dist -.next/ -favicon-formats.ts -custom.*[js, html] diff --git a/src/stale/hyperglass/hyperglass/ui/.eslintrc-delete.js b/src/stale/hyperglass/hyperglass/ui/.eslintrc-delete.js deleted file mode 100644 index cd4d95d..0000000 --- a/src/stale/hyperglass/hyperglass/ui/.eslintrc-delete.js +++ /dev/null @@ -1,69 +0,0 @@ -module.exports = { - root: true, - extends: ['eslint:recommended'], - env: { - es6: true, - node: true, - }, - parserOptions: { - ecmaVersion: 2020, - sourceType: 'module', - ecmaFeatures: { - jsx: true, - arrowFunctions: true, - }, - project: './tsconfig.json', - }, - overrides: [ - { - files: ['**/*.ts', '**/*.tsx'], - parser: '@typescript-eslint/parser', - settings: { - react: { version: 'detect' }, - 'import/resolver': { - typescript: {}, - }, - }, - env: { - browser: true, - node: true, - es6: true, - }, - extends: [ - 'eslint:recommended', - 'plugin:import/errors', - 'plugin:import/warnings', - 'plugin:import/typescript', - 'plugin:@typescript-eslint/recommended', - 'plugin:react/recommended', - 'plugin:react-hooks/recommended', - 'plugin:jsx-a11y/recommended', - 'plugin:prettier/recommended', - ], - rules: { - 'prettier/prettier': ['error', {}, { usePrettierrc: true }], - '@typescript-eslint/no-unused-vars': 'off', - '@typescript-eslint/no-unused-vars-experimental': 'error', - 'no-unused-vars': 'off', - 'react/jsx-uses-react': 'off', - 'react/react-in-jsx-scope': 'off', - 'comma-dangle': ['error', 'always-multiline'], - 'global-require': 'off', - 'import/no-dynamic-require': 'off', - 'import/prefer-default-export': 'off', - 'import/no-named-as-default-member': 'off', - '@typescript-eslint/no-inferrable-types': 'off', - '@typescript-eslint/explicit-function-return-type': 'off', - '@typescript-eslint/no-var-requires': 'off', - '@typescript-eslint/no-non-null-assertion': 'off', - '@typescript-eslint/no-namespace': 'off', - '@typescript-eslint/no-empty-interface': [ - 'error', - { - allowSingleExtends: true, - }, - ], - }, - }, - ], -}; diff --git a/src/stale/hyperglass/hyperglass/ui/.gitignore b/src/stale/hyperglass/hyperglass/ui/.gitignore deleted file mode 100644 index e544177..0000000 --- a/src/stale/hyperglass/hyperglass/ui/.gitignore +++ /dev/null @@ -1,20 +0,0 @@ -.DS_Store -.env* -hyperglass.json -custom.*[js, html] -*.tsbuildinfo -# dev/test files -TODO.txt -*.tmp* -test* -*.log -# generated theme file from hyperglass/hyperglass/render/templates/theme.sass.j2 -theme.sass -# generated JSON file from ingested & validated YAML config -frontend.json -# NPM modules -node_modules/ -# Downloaded Google Fonts -fonts/ -.next -out diff --git a/src/stale/hyperglass/hyperglass/ui/.prettierignore b/src/stale/hyperglass/hyperglass/ui/.prettierignore deleted file mode 100644 index fc2cfe7..0000000 --- a/src/stale/hyperglass/hyperglass/ui/.prettierignore +++ /dev/null @@ -1,10 +0,0 @@ -node_modules -dist -package.json -yarn.lock -package-lock.json -.eslintrc -tsconfig.json -.next/ -favicon-formats.ts -custom.*[js, html] diff --git a/src/stale/hyperglass/hyperglass/ui/.prettierrc b/src/stale/hyperglass/hyperglass/ui/.prettierrc deleted file mode 100644 index 354b46a..0000000 --- a/src/stale/hyperglass/hyperglass/ui/.prettierrc +++ /dev/null @@ -1,11 +0,0 @@ -{ - "semi": true, - "printWidth": 100, - "tabWidth": 2, - "singleQuote": true, - "bracketSpacing": true, - "jsxBracketSameLine": false, - "useTabs": false, - "arrowParens": "avoid", - "trailingComma": "all" -} diff --git a/src/stale/hyperglass/hyperglass/ui/README.md b/src/stale/hyperglass/hyperglass/ui/README.md deleted file mode 100644 index 7bb61f2..0000000 --- a/src/stale/hyperglass/hyperglass/ui/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# hyperglass-ui - -[hyperglass](https://github.com/thatmattlove/hyperglass) UI, written in [React](https://reactjs.org/), on [Next.js](https://nextjs.org/), with [Chakra UI](https://chakra-ui.com/). diff --git a/src/stale/hyperglass/hyperglass/ui/biome.json b/src/stale/hyperglass/hyperglass/ui/biome.json deleted file mode 100644 index 9ba7576..0000000 --- a/src/stale/hyperglass/hyperglass/ui/biome.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "$schema": "https://biomejs.dev/schemas/1.5.3/schema.json", - "extends": ["../../biome.json"] -} diff --git a/src/stale/hyperglass/hyperglass/ui/components/debugger.tsx b/src/stale/hyperglass/hyperglass/ui/components/debugger.tsx deleted file mode 100644 index 4c2fc28..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/debugger.tsx +++ /dev/null @@ -1,115 +0,0 @@ -import { - Tag, - Modal, - HStack, - Button, - ModalBody, - ModalHeader, - ModalOverlay, - ModalContent, - useDisclosure, - ModalCloseButton, -} from '@chakra-ui/react'; -import { useConfig } from '~/context'; -import { CodeBlock, DynamicIcon } from '~/elements'; -import { - useTheme, - useColorMode, - useColorValue, - useBreakpointValue, - // useHyperglassConfig, -} from '~/hooks'; - -import type { UseDisclosureReturn } from '@chakra-ui/react'; - -interface TViewer extends Pick { - title: string; - children: React.ReactNode; -} - -const Viewer = (props: TViewer): JSX.Element => { - const { title, isOpen, onClose, children } = props; - const bg = useColorValue('white', 'blackSolid.700'); - const color = useColorValue('black', 'white'); - return ( - - - - {title} - - - {children} - - - - ); -}; - -export const Debugger = (): JSX.Element => { - const { isOpen: configOpen, onOpen: onConfigOpen, onClose: configClose } = useDisclosure(); - const { isOpen: themeOpen, onOpen: onThemeOpen, onClose: themeClose } = useDisclosure(); - const { colorMode } = useColorMode(); - const config = useConfig(); - const theme = useTheme(); - const borderColor = useColorValue('gray.100', 'gray.600'); - const mediaSize = - useBreakpointValue({ base: 'SMALL', md: 'MEDIUM', lg: 'LARGE', xl: 'X-LARGE' }) ?? 'UNKNOWN'; - const tagSize = useBreakpointValue({ base: 'sm', lg: 'lg' }) ?? 'lg'; - const btnSize = useBreakpointValue({ base: 'xs', lg: 'sm' }) ?? 'sm'; - // const { refetch } = useHyperglassConfig(); - return ( - <> - - - {colorMode.toUpperCase()} - - - - {/* */} - - {mediaSize} - - - - {JSON.stringify(config, null, 4)} - - - {JSON.stringify(theme, null, 4)} - - - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/directive-info-modal.tsx b/src/stale/hyperglass/hyperglass/ui/components/directive-info-modal.tsx deleted file mode 100644 index 9b7b915..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/directive-info-modal.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import { - Modal, - ScaleFade, - ModalBody, - IconButton, - ModalHeader, - ModalOverlay, - ModalContent, - useDisclosure, - ModalCloseButton, -} from '@chakra-ui/react'; -import { DynamicIcon, Markdown } from '~/elements'; -import { useColorValue } from '~/hooks'; - -import type { ModalContentProps } from '@chakra-ui/react'; - -interface DirectiveInfoModalProps extends Omit { - title: string | null; - item: string | null; - name: string; - visible: boolean; -} - -export const DirectiveInfoModal = (props: DirectiveInfoModalProps): JSX.Element => { - const { visible, item, name, title, ...rest } = props; - const { isOpen, onOpen, onClose } = useDisclosure(); - const bg = useColorValue('whiteSolid.50', 'blackSolid.700'); - const color = useColorValue('black', 'white'); - if (item === null) { - return <>; - } - return ( - <> - - } - /> - - - - - {title} - - - - - - - - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/footer/button.tsx b/src/stale/hyperglass/hyperglass/ui/components/footer/button.tsx deleted file mode 100644 index 3546849..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/footer/button.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import { useMemo } from 'react'; -import { Button, Menu, MenuButton, MenuList } from '@chakra-ui/react'; -import { useConfig } from '~/context'; -import { Markdown } from '~/elements'; -import { useColorValue, useBreakpointValue, useOpposingColor, useStrf } from '~/hooks'; - -import type { MenuListProps } from '@chakra-ui/react'; -import type { Config } from '~/types'; - -interface FooterButtonProps extends Omit { - side: 'left' | 'right'; - title?: MenuListProps['children']; - content: string; -} - -/** - * Filter the configuration object based on values that are strings for formatting. - */ -function getConfigFmt(config: Config): Record { - const fmt = {} as Record; - for (const [k, v] of Object.entries(config)) { - if (typeof v === 'string') { - fmt[k] = v; - } - } - return fmt; -} - -export const FooterButton = (props: FooterButtonProps): JSX.Element => { - const { content, title, side, ...rest } = props; - - const config = useConfig(); - const strF = useStrf(); - const fmt = useMemo(() => getConfigFmt(config), [config]); - const fmtContent = useMemo(() => strF(content, fmt), [fmt, content, strF]); - - const placement = side === 'left' ? 'top' : side === 'right' ? 'top-end' : undefined; - const bg = useColorValue('white', 'gray.900'); - const color = useOpposingColor(bg); - const size = useBreakpointValue({ base: 'xs', lg: 'sm' }); - - return ( - - - {title} - - - - - - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/footer/color-mode.tsx b/src/stale/hyperglass/hyperglass/ui/components/footer/color-mode.tsx deleted file mode 100644 index 5059b97..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/footer/color-mode.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import { forwardRef } from 'react'; -import { Button, Tooltip } from '@chakra-ui/react'; -import { Switch, Case } from 'react-if'; -import { DynamicIcon } from '~/elements'; -import { useOpposingColor, useColorMode, useColorValue, useBreakpointValue } from '~/hooks'; - -import type { ButtonProps } from '@chakra-ui/react'; - -interface ColorModeToggleProps extends Omit { - size?: string | number; -} - -export const ColorModeToggle = forwardRef( - (props: ColorModeToggleProps, ref) => { - const { size = '1.5rem', ...rest } = props; - const { colorMode, toggleColorMode } = useColorMode(); - - const bg = useColorValue('primary.500', 'yellow.300'); - const color = useOpposingColor(bg); - const label = useColorValue('Switch to dark mode', 'Switch to light mode'); - const btnSize = useBreakpointValue({ base: 'xs', lg: 'sm' }); - - return ( - - - - ); - }, -); diff --git a/src/stale/hyperglass/hyperglass/ui/components/footer/footer.tsx b/src/stale/hyperglass/hyperglass/ui/components/footer/footer.tsx deleted file mode 100644 index 17d3fea..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/footer/footer.tsx +++ /dev/null @@ -1,88 +0,0 @@ -import { Flex, HStack, useToken } from '@chakra-ui/react'; -import { useMemo } from 'react'; -import { useConfig } from '~/context'; -import { DynamicIcon } from '~/elements'; -import { useBreakpointValue, useColorValue, useMobile } from '~/hooks'; -import { isLink, isMenu } from '~/types'; -import { FooterButton } from './button'; -import { ColorModeToggle } from './color-mode'; -import { FooterLink } from './link'; - -import type { ButtonProps, LinkProps } from '@chakra-ui/react'; -import type { Link, Menu } from '~/types'; - -type MenuItems = (Link | Menu)[]; - -function buildItems(links: Link[], menus: Menu[]): [MenuItems, MenuItems] { - const leftLinks = links.filter(link => link.side === 'left'); - const leftMenus = menus.filter(menu => menu.side === 'left'); - const rightLinks = links.filter(link => link.side === 'right'); - const rightMenus = menus.filter(menu => menu.side === 'right'); - - const left = [...leftLinks, ...leftMenus].sort((a, b) => (a.order > b.order ? 1 : -1)); - const right = [...rightLinks, ...rightMenus].sort((a, b) => (a.order > b.order ? 1 : -1)); - return [left, right]; -} - -const LinkOnSide = (props: { item: ArrayElement; side: 'left' | 'right' }) => { - const { item, side } = props; - if (isLink(item)) { - const icon: Partial = {}; - - if (item.showIcon) { - icon.rightIcon = ; - } - return ; - } - if (isMenu(item)) { - return ; - } -}; - -export const Footer = (): JSX.Element => { - const { web, content } = useConfig(); - - const footerBg = useColorValue('blackAlpha.50', 'whiteAlpha.100'); - const footerColor = useColorValue('black', 'white'); - - const size = useBreakpointValue({ base: useToken('sizes', 4), lg: useToken('sizes', 6) }); - - const isMobile = useMobile(); - - const [left, right] = useMemo(() => buildItems(web.links, web.menus), [web.links, web.menus]); - - return ( - - {left.map(item => ( - - ))} - {!isMobile && } - {right.map(item => ( - - ))} - {web.credit.enable && ( - } - /> - )} - - - - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/footer/index.ts b/src/stale/hyperglass/hyperglass/ui/components/footer/index.ts deleted file mode 100644 index a058eae..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/footer/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './footer'; diff --git a/src/stale/hyperglass/hyperglass/ui/components/footer/link.tsx b/src/stale/hyperglass/hyperglass/ui/components/footer/link.tsx deleted file mode 100644 index cac171e..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/footer/link.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { Button, Link } from '@chakra-ui/react'; -import { useBreakpointValue } from '~/hooks'; - -import type { ButtonProps, LinkProps } from '@chakra-ui/react'; - -type FooterLinkProps = ButtonProps & LinkProps & { title: string }; - -export const FooterLink = (props: FooterLinkProps): JSX.Element => { - const { title } = props; - const btnSize = useBreakpointValue({ base: 'xs', lg: 'sm' }); - return ( - - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/form-field.tsx b/src/stale/hyperglass/hyperglass/ui/components/form-field.tsx deleted file mode 100644 index 63f02e0..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/form-field.tsx +++ /dev/null @@ -1,75 +0,0 @@ -import { Flex, FormControl, FormErrorMessage, FormLabel } from '@chakra-ui/react'; -import { useMemo } from 'react'; -import { useFormContext } from 'react-hook-form'; -import { If, Then } from 'react-if'; -import { useBooleanValue, useColorValue } from '~/hooks'; - -import type { FormControlProps } from '@chakra-ui/react'; -import type { FieldError } from 'react-hook-form'; -import type { FormData } from '~/types'; - -interface FormFieldProps extends FormControlProps { - name: string; - label: string; - hiddenLabels?: boolean; - labelAddOn?: React.ReactNode; - fieldAddOn?: React.ReactNode; -} - -export const FormField = (props: FormFieldProps): JSX.Element => { - const { name, label, children, labelAddOn, fieldAddOn, hiddenLabels = false, ...rest } = props; - const labelColor = useColorValue('blackAlpha.700', 'whiteAlpha.700'); - const errorColor = useColorValue('red.500', 'red.300'); - const opacity = useBooleanValue(hiddenLabels, 0, undefined); - - const { formState } = useFormContext(); - - const error = useMemo(() => { - if (name in formState.errors) { - console.group(`Error on field '${label}'`); - console.warn(formState.errors[name as keyof FormData]); - console.groupEnd(); - return formState.errors[name as keyof FormData] as FieldError; - } - return null; - }, [formState, label, name]); - - return ( - - - {label} - - {labelAddOn} - - - {children} - - - - {fieldAddOn} - - - - {error?.message} - - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/greeting.tsx b/src/stale/hyperglass/hyperglass/ui/components/greeting.tsx deleted file mode 100644 index 7ee576a..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/greeting.tsx +++ /dev/null @@ -1,70 +0,0 @@ -import { useEffect } from 'react'; -import { - Modal, - Button, - ModalBody, - ModalHeader, - ModalFooter, - ModalOverlay, - ModalContent, - ModalCloseButton, -} from '@chakra-ui/react'; -import { If, Then } from 'react-if'; -import { Markdown } from '~/elements'; -import { useConfig } from '~/context'; -import { useGreeting, useColorValue, useOpposingColor } from '~/hooks'; - -import type { ModalContentProps } from '@chakra-ui/react'; - -export const Greeting = (props: ModalContentProps): JSX.Element => { - const { web, content } = useConfig(); - const { isAck, isOpen, open, ack } = useGreeting(); - - const bg = useColorValue('white', 'gray.800'); - const color = useOpposingColor(bg); - - useEffect(() => { - if (!web.greeting.enable && !web.greeting.required) { - ack(true, false); - } - if (!isAck && web.greeting.enable) { - open(); - } - }, [isAck, open, web.greeting.enable, web.greeting.required, ack]); - return ( - ack(false, web.greeting.required)} - isOpen={isOpen} - motionPreset="slideInBottom" - closeOnEsc={web.greeting.required} - closeOnOverlayClick={web.greeting.required} - > - - - {web.greeting.title} - - - - - - - - - - - - - - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/header/header.tsx b/src/stale/hyperglass/hyperglass/ui/components/header/header.tsx deleted file mode 100644 index b36470a..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/header/header.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { Flex, ScaleFade } from '@chakra-ui/react'; -import { motionChakra } from '~/elements'; -import { useBooleanValue, useBreakpointValue, useFormInteractive } from '~/hooks'; -import { Title } from './title'; - -const Wrapper = motionChakra('header', { - baseStyle: { display: 'flex', px: 4, pt: 6, minH: 16, w: 'full', flex: '0 1 auto' }, -}); - -export const Header = (): JSX.Element => { - const formInteractive = useFormInteractive(); - - const titleWidth = useBooleanValue( - formInteractive, - { base: '75%', lg: '50%' }, - { base: '75%', lg: '75%' }, - ); - - return ( - - - - - </Flex> - </ScaleFade> - </Wrapper> - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/header/index.ts b/src/stale/hyperglass/hyperglass/ui/components/header/index.ts deleted file mode 100644 index 677ca79..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/header/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './header'; diff --git a/src/stale/hyperglass/hyperglass/ui/components/header/logo.tsx b/src/stale/hyperglass/hyperglass/ui/components/header/logo.tsx deleted file mode 100644 index a5aa6ec..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/header/logo.tsx +++ /dev/null @@ -1,67 +0,0 @@ -import { Image, Skeleton } from '@chakra-ui/react'; -import { useCallback, useMemo, useState } from 'react'; -import { useConfig } from '~/context'; -import { useColorValue } from '~/hooks'; - -import type { ImageProps } from '@chakra-ui/react'; - -/** - * Custom hook to handle loading the user's logo, errors loading the logo, and color mode changes. - */ -function useLogo(): [string, () => void] { - const { web } = useConfig(); - const { darkFormat, lightFormat } = web.logo; - - const src = useColorValue(`/images/light${darkFormat}`, `/images/dark${lightFormat}`); - - // Use the hyperglass logo if the user's logo can't be loaded for whatever reason. - const [fallback, setSource] = useState<string | null>(null); - - // If the user image cannot be loaded, log an error to the console and set the fallback image. - const setFallback = useCallback(() => { - console.warn(`Error loading image from '${src}'`); - setSource('https://res.cloudinary.com/hyperglass/image/upload/v1593916013/logo-light.svg'); - }, [src]); - - // Only return the fallback image if it's been set. - return useMemo(() => [fallback ?? src, setFallback], [fallback, setFallback, src]); -} - -export const Logo = (props: ImageProps): JSX.Element => { - const { web } = useConfig(); - const { width } = web.logo; - - const skeletonA = useColorValue('whiteSolid.100', 'blackSolid.800'); - const skeletonB = useColorValue('light.500', 'dark.500'); - - const [source, setFallback] = useLogo(); - - return ( - <Image - src={source} - alt={web.text.title} - onError={setFallback} - maxW={{ base: '100%', md: width }} - width="auto" - css={{ - userDrag: 'none', - userSelect: 'none', - msUserSelect: 'none', - MozUserSelect: 'none', - WebkitUserDrag: 'none', - WebkitUserSelect: 'none', - }} - fallback={ - <Skeleton - isLoaded={false} - borderRadius="md" - endColor={skeletonB} - startColor={skeletonA} - width={{ base: 64, lg: 80 }} - height={{ base: 12, lg: 16 }} - /> - } - {...props} - /> - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/header/subtitle-only.tsx b/src/stale/hyperglass/hyperglass/ui/components/header/subtitle-only.tsx deleted file mode 100644 index 0f9a0cb..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/header/subtitle-only.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { Heading } from '@chakra-ui/react'; -import { useConfig } from '~/context'; -import { useBreakpointValue } from '~/hooks'; -import { useTitleSize } from './use-title-size'; - -export const SubtitleOnly = (): JSX.Element => { - const { web } = useConfig(); - const sizeSm = useTitleSize(web.text.subtitle, 'sm'); - const fontSize = useBreakpointValue({ base: sizeSm, lg: 'xl' }); - - return ( - <Heading - as="h3" - fontWeight="normal" - fontSize={fontSize} - whiteSpace="break-spaces" - textAlign={{ base: 'left', xl: 'center' }} - > - {web.text.subtitle} - </Heading> - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/header/title-only.tsx b/src/stale/hyperglass/hyperglass/ui/components/header/title-only.tsx deleted file mode 100644 index 4b12d1a..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/header/title-only.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { Heading } from '@chakra-ui/react'; -import { useConfig } from '~/context'; -import { useBooleanValue, useFormInteractive } from '~/hooks'; -import { useTitleSize } from './use-title-size'; - -export const TitleOnly = (): JSX.Element => { - const { web } = useConfig(); - const formInteractive = useFormInteractive(); - const margin = useBooleanValue(formInteractive, 0, 2); - const sizeSm = useTitleSize(web.text.title, '2xl', []); - - return ( - <Heading as="h1" mb={margin} fontSize={{ base: sizeSm, lg: '5xl' }}> - {web.text.title} - </Heading> - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/header/title.tsx b/src/stale/hyperglass/hyperglass/ui/components/header/title.tsx deleted file mode 100644 index c69b036..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/header/title.tsx +++ /dev/null @@ -1,168 +0,0 @@ -import { Button, Flex, VStack } from '@chakra-ui/react'; -import { motion } from 'framer-motion'; -import { isSafari } from 'react-device-detect'; -import { Case, Switch } from 'react-if'; -import { useConfig } from '~/context'; -import { useFormInteractive, useFormState, useMobile } from '~/hooks'; -import { Logo } from './logo'; -import { SubtitleOnly } from './subtitle-only'; -import { TitleOnly } from './title-only'; - -import type { FlexProps, StackProps } from '@chakra-ui/react'; -import type { MotionProps } from 'framer-motion'; - -type DWrapperProps = Omit<StackProps, 'transition'> & MotionProps; -type MWrapperProps = Omit<StackProps, 'transition'> & MotionProps; -type WrapperProps = Partial<MotionProps & Omit<StackProps, 'transition'>>; - -const AnimatedVStack = motion(VStack); -const AnimatedFlex = motion(Flex); - -/** - * Title wrapper for mobile devices, breakpoints sm & md. - */ -const MWrapper = (props: MWrapperProps): JSX.Element => { - const formInteractive = useFormInteractive(); - return ( - <AnimatedVStack - layout - spacing={1} - alignItems={formInteractive ? 'center' : 'flex-start'} - {...props} - /> - ); -}; - -/** - * Title wrapper for desktop devices, breakpoints lg & xl. - */ -const DWrapper = (props: DWrapperProps): JSX.Element => { - const formInteractive = useFormInteractive(); - return ( - <AnimatedVStack - spacing={1} - initial="main" - alignItems="center" - animate={formInteractive} - transition={{ damping: 15, type: 'spring', stiffness: 100 }} - variants={{ results: { scale: 0.5 }, form: { scale: 1 } }} - maxWidth="75%" - {...props} - /> - ); -}; - -/** - * Universal wrapper for title sub-components, which will be different depending on the - * `title_mode` configuration variable. - */ -const TitleWrapper = (props: DWrapperProps | MWrapperProps): JSX.Element => { - const isMobile = useMobile(); - return ( - <> - {isMobile ? ( - <MWrapper {...(props as MWrapperProps)} /> - ) : ( - <DWrapper {...(props as DWrapperProps)} /> - )} - </> - ); -}; - -/** - * Title sub-component if `title_mode` is set to `text_only`. - */ -const TextOnly = (props: WrapperProps): JSX.Element => { - return ( - <TitleWrapper {...props}> - <TitleOnly /> - <SubtitleOnly /> - </TitleWrapper> - ); -}; - -/** - * Title sub-component if `title_mode` is set to `logo_only`. Renders only the logo. - */ -const LogoOnly = (props: WrapperProps): JSX.Element => ( - <TitleWrapper {...props}> - <Logo /> - </TitleWrapper> -); - -/** - * Title sub-component if `title_mode` is set to `logo_subtitle`. Renders the logo with the - * subtitle underneath. - */ -const LogoSubtitle = (props: WrapperProps): JSX.Element => ( - <TitleWrapper {...props}> - <Logo /> - <SubtitleOnly /> - </TitleWrapper> -); - -/** - * Title sub-component if `title_mode` is set to `all`. Renders the logo, title, and subtitle. - */ -const All = (props: WrapperProps): JSX.Element => ( - <TitleWrapper {...props}> - <Logo /> - <TextOnly mt={2} /> - </TitleWrapper> -); - -/** - * Title component which renders sub-components based on the `title_mode` configuration variable. - */ -export const Title = (props: FlexProps): JSX.Element => { - const { fontSize, ...rest } = props; - const { web } = useConfig(); - const { titleMode } = web.text; - - const reset = useFormState(s => s.reset); - const formInteractive = useFormInteractive(); - - return ( - <AnimatedFlex - px={0} - flexWrap="wrap" - flexDir="column" - animate={{ height: formInteractive ? undefined : '20vh' }} - justifyContent="center" - /* flexBasis - This is a fix for Safari specifically. LMGTFY: Safari flex-basis width. Nutshell: Safari - is stupid, in that it infers the default flex-basis from the width, 100%. Other browsers - don't do this. Without the below fix, the logo will appear gigantic, filling the entire - div up to the parent's max-width. The fix is to hard-code a flex-basis width. - */ - flexBasis={{ base: '100%', lg: isSafari ? '33%' : '100%' }} - mt={{ md: formInteractive ? undefined : 'auto' }} - {...rest} - > - <Button - px={0} - variant="link" - flexWrap="wrap" - flexDir="column" - onClick={async () => await reset()} - _focus={{ boxShadow: 'none' }} - _hover={{ textDecoration: 'none' }} - > - <Switch> - <Case condition={titleMode === 'text_only'}> - <TextOnly width={web.logo.width} /> - </Case> - <Case condition={titleMode === 'logo_only'}> - <LogoOnly width={web.logo.width} /> - </Case> - <Case condition={titleMode === 'logo_subtitle'}> - <LogoSubtitle width={web.logo.width} /> - </Case> - <Case condition={titleMode === 'all'}> - <All width={web.logo.width} /> - </Case> - </Switch> - </Button> - </AnimatedFlex> - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/header/use-title-size.ts b/src/stale/hyperglass/hyperglass/ui/components/header/use-title-size.ts deleted file mode 100644 index e6223c9..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/header/use-title-size.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { useMemo, useState } from 'react'; -import { useToken } from '@chakra-ui/react'; -import { useMobile } from '~/hooks'; - -// Mobile: -// xs: 32 -// sm: 28 -// md: 24 -// lg: 20 -// xl: 16 -// 2xl: 14 -// 3xl: 12 -// 4xl: 10 -// 5xl: 7 -type Sizes = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | '5xl'; - -export function useTitleSize(title: string, defaultSize: Sizes, deps: unknown[] = []): string { - const [size, setSize] = useState<Sizes>(defaultSize); - const realSize = useToken('fontSizes', size) as string; - const isMobile = useMobile(); - function getSize(l: number): void { - switch (true) { - case l > 32: - setSize('xs'); - break; - case l <= 32 && l > 28: - setSize('xs'); - break; - case l <= 28 && l > 24: - setSize('sm'); - break; - case l <= 24 && l > 20: - setSize('md'); - break; - case l <= 20 && l > 16: - setSize('lg'); - break; - case l <= 16 && l > 14: - setSize('xl'); - break; - case l <= 14 && l > 12: - setSize('2xl'); - break; - case l <= 12 && l > 10: - setSize('3xl'); - break; - case l <= 10 && l > 7: - setSize('4xl'); - break; - case l <= 7: - setSize('5xl'); - break; - } - } - return useMemo(() => { - getSize(title.length); - return realSize; - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [title, isMobile, realSize, ...deps]); -} diff --git a/src/stale/hyperglass/hyperglass/ui/components/index.ts b/src/stale/hyperglass/hyperglass/ui/components/index.ts deleted file mode 100644 index 6c0f318..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/index.ts +++ /dev/null @@ -1,30 +0,0 @@ -/** - * The components directory contains React components that handle logic. - * - * Generally, components that call hooks or reference configuration, or API types should be in - * components. - */ - -export * from './debugger'; -export * from './directive-info-modal'; -export * from './footer'; -export * from './form-field'; -export * from './greeting'; -export * from './header'; -export * from './layout'; -export * from './location-card'; -export * from './looking-glass-form'; -export * from './meta'; -export * from './output'; -export * from './path'; -export * from './prompt'; -export * from './query-location'; -export * from './query-target'; -export * from './query-type'; -export * from './reset-button'; -export * from './resolved-target'; -export * from './results'; -export * from './select'; -export * from './submit-button'; -export * from './table'; -export * from './user-ip'; diff --git a/src/stale/hyperglass/hyperglass/ui/components/layout.tsx b/src/stale/hyperglass/hyperglass/ui/components/layout.tsx deleted file mode 100644 index 585a73a..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/layout.tsx +++ /dev/null @@ -1,76 +0,0 @@ -import { Flex } from '@chakra-ui/react'; -import { useCallback, useRef } from 'react'; -import { isSafari } from 'react-device-detect'; -import { If, Then } from 'react-if'; -import { Debugger, Footer, Greeting, Header, ResetButton } from '~/components'; -import { useConfig } from '~/context'; -import { motionChakra } from '~/elements'; -import { useFormState } from '~/hooks'; - -import type { FlexProps } from '@chakra-ui/react'; - -const Main = motionChakra('main', { - baseStyle: { - px: 4, - py: 0, - w: '100%', - display: 'flex', - flex: '1 1 auto', - flexDir: 'column', - textAlign: 'center', - alignItems: 'center', - justifyContent: 'start', - }, -}); - -export const Layout = (props: FlexProps): JSX.Element => { - const { developerMode } = useConfig(); - const { setStatus, reset } = useFormState( - useCallback(({ setStatus, reset }) => ({ setStatus, reset }), []), - ); - - const containerRef = useRef<HTMLDivElement>({} as HTMLDivElement); - - async function handleReset() { - containerRef.current.scrollIntoView({ behavior: 'smooth', block: 'start' }); - setStatus('form'); - reset(); - } - - return ( - <> - <Flex - w="100%" - flex="1 0 auto" - flexDir="column" - id="__hyperglass" - ref={containerRef} - /** minHeight - * This is a Safari-specific fix. Without it, the footer will appear to be "under" the - * viewport. Safari needs `-webkit-fill-available`, but other browsers need `100vh`. - * @see https://allthingssmitty.com/2020/05/11/css-fix-for-100vh-in-mobile-webkit/ - */ - minHeight={isSafari ? '-webkit-fill-available' : '100vh'} - > - <Header /> - <Main - layout - animate={{ opacity: 1, y: 0 }} - transition={{ duration: 0.3 }} - exit={{ opacity: 0, x: -300 }} - initial={{ opacity: 0, y: 300 }} - > - {props.children} - </Main> - <Footer /> - <If condition={developerMode}> - <Then> - <Debugger /> - </Then> - </If> - <ResetButton developerMode={developerMode} resetForm={handleReset} /> - </Flex> - <Greeting /> - </> - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/location-card.tsx b/src/stale/hyperglass/hyperglass/ui/components/location-card.tsx deleted file mode 100644 index 6797ac9..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/location-card.tsx +++ /dev/null @@ -1,107 +0,0 @@ -import { useMemo, useState } from 'react'; -import { Flex, Avatar, chakra } from '@chakra-ui/react'; -import { motionChakra } from '~/elements'; -import { useColorValue, useOpposingColor } from '~/hooks'; - -import type { SingleOption } from '~/types'; -import type { LocationOption } from './query-location'; - -interface LocationCardProps { - option: SingleOption; - defaultChecked: boolean; - onChange(a: 'add' | 'remove', v: SingleOption): void; - hasError: boolean; -} - -const LocationCardWrapper = motionChakra('div', { - baseStyle: { - py: 4, - px: 6, - minW: 'xs', - maxW: 'md', - mx: 'auto', - shadow: 'sm', - rounded: 'lg', - cursor: 'pointer', - borderWidth: '1px', - borderStyle: 'solid', - }, -}); - -export const LocationCard = (props: LocationCardProps): JSX.Element => { - const { option, onChange, defaultChecked, hasError } = props; - const { label } = option; - const [isChecked, setChecked] = useState(defaultChecked); - - function handleChange(value: LocationOption) { - if (isChecked) { - setChecked(false); - onChange('remove', value); - } else { - setChecked(true); - onChange('add', value); - } - } - - const bg = useColorValue('white', 'blackSolid.600'); - const imageBorder = useColorValue('gray.600', 'whiteAlpha.800'); - const fg = useOpposingColor(bg); - const checkedBorder = useColorValue('blue.400', 'blue.300'); - const errorBorder = useColorValue('red.500', 'red.300'); - - const borderColor = useMemo( - () => - hasError && isChecked - ? // Highlight red when there are no overlapping query types for the locations selected. - errorBorder - : isChecked && !hasError - ? // Highlight blue when any location is selected and there is no error. - checkedBorder - : // Otherwise, no border. - 'transparent', - - [hasError, isChecked, checkedBorder, errorBorder], - ); - return ( - <LocationCardWrapper - bg={bg} - key={label} - whileHover={{ scale: 1.05 }} - borderColor={borderColor} - onClick={(e: React.MouseEvent) => { - e.preventDefault(); - handleChange(option); - }} - > - <> - <Flex justifyContent="space-between" alignItems="center"> - <chakra.h2 - color={fg} - fontWeight="bold" - mt={{ base: 2, md: 0 }} - fontSize={{ base: 'lg', md: 'xl' }} - > - {label} - </chakra.h2> - <Avatar - color={fg} - name={label} - boxSize={12} - rounded="full" - borderWidth={1} - bg="whiteAlpha.300" - borderStyle="solid" - borderColor={imageBorder} - src={(option.data?.avatar as string) ?? undefined} - /> - </Flex> - - {option?.data?.description && ( - <chakra.p mt={2} color={fg} opacity={0.6} fontSize="sm"> - {option.data.description as string} - </chakra.p> - )} - </> - </LocationCardWrapper> - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/looking-glass-form.tsx b/src/stale/hyperglass/hyperglass/ui/components/looking-glass-form.tsx deleted file mode 100644 index 2da4633..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/looking-glass-form.tsx +++ /dev/null @@ -1,242 +0,0 @@ -import { Flex, ScaleFade, SlideFade, chakra } from '@chakra-ui/react'; -import { vestResolver } from '@hookform/resolvers/vest'; -import { useCallback, useEffect, useMemo } from 'react'; -import isEqual from 'react-fast-compare'; -import { FormProvider, useForm } from 'react-hook-form'; -import vest, { test, enforce } from 'vest'; -import { - DirectiveInfoModal, - FormField, - QueryLocation, - QueryTarget, - QueryType, - SubmitButton, -} from '~/components'; -import { useConfig } from '~/context'; -import { FormRow } from '~/elements'; -import { useDevice, useFormState, useGreeting, useStrf } from '~/hooks'; -import { Directive, isQueryField, isString } from '~/types'; -import { isFQDN } from '~/util'; - -import type { FormData, OnChangeArgs } from '~/types'; - -export const LookingGlassForm = (): JSX.Element => { - const { web, messages } = useConfig(); - - const greetingReady = useGreeting(s => s.greetingReady); - - const getDevice = useDevice(); - const strF = useStrf(); - const setLoading = useFormState(s => s.setLoading); - const setStatus = useFormState(s => s.setStatus); - const locationChange = useFormState(s => s.locationChange); - const setTarget = useFormState(s => s.setTarget); - const setFormValue = useFormState(s => s.setFormValue); - const { form, filtered, selections } = useFormState( - useCallback(({ form, filtered, selections }) => ({ form, filtered, selections }), []), - isEqual, - ); - - const getDirective = useFormState(useCallback(s => s.getDirective, [])); - const resolvedOpen = useFormState(useCallback(s => s.resolvedOpen, [])); - const resetForm = useFormState(useCallback(s => s.reset, [])); - - const noQueryType = strF(messages.noInput, { field: web.text.queryType }); - const noQueryLoc = strF(messages.noInput, { field: web.text.queryLocation }); - const noQueryTarget = strF(messages.noInput, { field: web.text.queryTarget }); - - const queryTypes = useMemo(() => filtered.types.map(t => t.id), [filtered.types]); - - const formSchema = vest.create((data: FormData = {} as FormData) => { - test('queryLocation', noQueryLoc, () => { - enforce(data.queryLocation).isArrayOf(enforce.isString()).isNotEmpty(); - }); - test('queryTarget', noQueryTarget, () => { - enforce(data.queryTarget).isArrayOf(enforce.isString()).isNotEmpty(); - }); - test('queryType', noQueryType, () => { - enforce(data.queryType).inside(queryTypes); - }); - }); - - const formInstance = useForm<FormData>({ - resolver: vestResolver(formSchema), - defaultValues: { - queryTarget: [], - queryLocation: [], - queryType: '', - }, - }); - - const { handleSubmit, register, setValue, setError, clearErrors } = formInstance; - - const isFqdnQuery = useCallback( - (target: string | string[], fieldType: Directive['fieldType'] | null): boolean => - (typeof target === 'string' || Array.isArray(target)) && - fieldType === 'text' && - isFQDN(target), - [], - ); - - const directive = useMemo<Directive | null>(() => { - const tmp = getDirective(); - if (tmp !== null && tmp.fieldType === null) { - setFormValue('queryTarget', ['null']); - setValue('queryTarget', ['null']); - } - return tmp; - }, [form.queryType, form.queryLocation, getDirective]); - - function submitHandler(): void { - if (process.env.NODE_ENV === 'development') { - console.table({ - 'Query Location': form.queryLocation.toString(), - 'Query Type': form.queryType, - 'Query Target': form.queryTarget, - 'Selected Directive': directive?.name ?? null, - }); - } - - // Before submitting a query, make sure the greeting is acknowledged if required. This should - // be handled before loading the app, but people be sneaky. - if (!greetingReady) { - resetForm(); - location.reload(); - return; - } - - // Determine if queryTarget is an FQDN. - const isFqdn = isFqdnQuery(form.queryTarget, directive?.fieldType ?? null); - - if (greetingReady && !isFqdn) { - setStatus('results'); - return; - } - - if (greetingReady && isFqdn) { - setLoading(true); - resolvedOpen(); - return; - } - console.group('%cSomething went wrong', 'color:red;'); - console.table({ - 'Greeting Required': web.greeting.required, - 'Greeting Ready': greetingReady, - 'Query Target': form.queryTarget, - 'Query Type': form.queryType, - 'Is FQDN': isFqdn, - }); - console.groupEnd(); - } - - const handleLocChange = (locations: string[]) => - locationChange(locations, { setError, clearErrors, getDevice, text: web.text }); - - function handleChange(e: OnChangeArgs): void { - // Signal the field & value to react-hook-form. - if (isQueryField(e.field)) { - setValue(e.field, e.value); - } else { - throw new Error(`Field '${e.field}' is not a valid form field.`); - } - - if (e.field === 'queryLocation' && Array.isArray(e.value)) { - handleLocChange(e.value); - } else if (e.field === 'queryType' && isString(e.value)) { - setValue('queryType', e.value); - setFormValue('queryType', e.value); - if (form.queryTarget.length !== 0) { - // Reset queryTarget as well, so that, for example, selecting BGP Community, and selecting - // a community, then changing the queryType to BGP Route doesn't preserve the selected - // community as the queryTarget. - setFormValue('queryTarget', []); - setTarget({ display: '' }); - } - } else if (e.field === 'queryTarget') { - if (isString(e.value)) { - setFormValue('queryTarget', [e.value]); - setValue('queryTarget', [e.value]); - } - if (Array.isArray(e.value)) { - setFormValue('queryTarget', e.value); - setValue('queryTarget', e.value); - } - } - } - - useEffect(() => { - register('queryLocation', { required: true }); - register('queryType', { required: true }); - }, [register]); - - return ( - <FormProvider {...formInstance}> - <chakra.form - p={0} - my={4} - w="100%" - mx="auto" - textAlign="left" - maxW={{ base: '100%', lg: '75%' }} - onSubmit={handleSubmit(submitHandler)} - > - <FormRow> - <FormField name="queryLocation" label={web.text.queryLocation}> - <QueryLocation onChange={handleChange} label={web.text.queryLocation} /> - </FormField> - </FormRow> - <FormRow> - <SlideFade offsetX={-100} in={filtered.types.length > 0} unmountOnExit> - <FormField - name="queryType" - label={web.text.queryType} - labelAddOn={ - directive !== null && ( - <DirectiveInfoModal - name="queryType" - title={directive.name ?? null} - item={directive.info ?? null} - visible={selections.queryType !== null && directive.info !== null} - /> - ) - } - > - <QueryType onChange={handleChange} label={web.text.queryType} /> - </FormField> - </SlideFade> - <SlideFade - offsetX={100} - in={directive !== null && directive.fieldType !== null} - unmountOnExit - > - {directive !== null && ( - <FormField name="queryTarget" label={web.text.queryTarget}> - <QueryTarget - name="queryTarget" - register={register} - onChange={handleChange} - placeholder={directive.description} - /> - </FormField> - )} - </SlideFade> - </FormRow> - <FormRow mt={0} justifyContent="flex-end"> - <Flex - my={2} - w="100%" - ml="auto" - maxW="100%" - flex="0 0 0" - flexDir="column" - mr={{ base: 0, lg: 2 }} - > - <ScaleFade initialScale={0.5} in={form.queryTarget.length !== 0}> - <SubmitButton /> - </ScaleFade> - </Flex> - </FormRow> - </chakra.form> - </FormProvider> - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/meta.tsx b/src/stale/hyperglass/hyperglass/ui/components/meta.tsx deleted file mode 100644 index a5c20ae..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/meta.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import { useEffect, useState } from 'react'; -import Head from 'next/head'; -import { useConfig } from '~/context'; - -export const Meta = (): JSX.Element => { - const config = useConfig(); - const [location, setLocation] = useState('/'); - - const { - siteTitle: title = 'hyperglass', - siteDescription: description = 'Network Looking Glass', - } = useConfig(); - - const siteName = `${title} - ${description}`; - - useEffect(() => { - if (typeof window !== 'undefined' && location === '/') { - setLocation(window.location.href); - } - }, [location]); - - return ( - <Head> - <title key="title">{title} - - - - - - - - - - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/output/bgp-table.tsx b/src/stale/hyperglass/hyperglass/ui/components/output/bgp-table.tsx deleted file mode 100644 index 670194e..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/output/bgp-table.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import { Flex } from '@chakra-ui/react'; -import { Table } from '~/components'; -import { useConfig } from '~/context'; -import { Cell } from './cell'; - -import type { FlexProps } from '@chakra-ui/react'; -import type { TableColumn, ParsedDataField, CellRenderProps } from '~/types'; - -type BGPTableProps = Swap; - -function makeColumns(fields: ParsedDataField[]): TableColumn[] { - return fields.map(pair => { - const [header, accessor, align] = pair; - - const columnConfig = { - align, - accessor, - hidden: false, - Header: header, - } as TableColumn; - - if (align === null) { - columnConfig.hidden = true; - } - - return columnConfig; - }); -} - -export const BGPTable = (props: BGPTableProps): JSX.Element => { - const { children: data, ...rest } = props; - const { parsedDataFields } = useConfig(); - const columns = makeColumns(parsedDataFields); - - return ( - - } - /> - - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/output/cell.tsx b/src/stale/hyperglass/hyperglass/ui/components/output/cell.tsx deleted file mode 100644 index 6bf12b7..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/output/cell.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import { MonoField, Active, Weight, Age, Communities, RPKIState, ASPath } from './fields'; - -import type { CellRenderProps } from '~/types'; - -interface CellProps { - data: CellRenderProps; - rawData: StructuredResponse; -} - -export const Cell = (props: CellProps): JSX.Element => { - const { data, rawData } = props; - const cellId = data.column.id as keyof Route; - const component = { - med: , - age: , - prefix: , - next_hop: , - peer_rid: , - source_as: , - active: , - source_rid: , - local_preference: , - communities: , - as_path: , - rpki_state: , - weight: , - }; - return component[cellId] ?? ''; -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/output/fields.tsx b/src/stale/hyperglass/hyperglass/ui/components/output/fields.tsx deleted file mode 100644 index a24857a..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/output/fields.tsx +++ /dev/null @@ -1,233 +0,0 @@ -import { Box, Flex, Link, Menu, MenuButton, MenuList, Text, Tooltip } from '@chakra-ui/react'; -import dayjs from 'dayjs'; -import relativeTimePlugin from 'dayjs/plugin/relativeTime'; -import utcPlugin from 'dayjs/plugin/utc'; -import { forwardRef } from 'react'; -import { Else, If, Then } from 'react-if'; -import { useConfig } from '~/context'; -import { DynamicIcon } from '~/elements'; -import { useColorValue, useOpposingColor } from '~/hooks'; - -import type { TextProps } from '@chakra-ui/react'; - -interface ActiveProps { - isActive: boolean; -} - -interface MonoFieldProps extends TextProps { - v: React.ReactNode; -} - -interface AgeProps extends TextProps { - inSeconds: number; -} - -interface WeightProps extends TextProps { - weight: number; - winningWeight: 'low' | 'high'; -} - -interface ASPathProps { - path: number[]; - active: boolean; -} - -interface CommunitiesProps { - communities: string[]; -} - -interface RPKIStateProps { - state: - | 0 // Invalid - | 1 // Valid - | 2 // Unknown - | 3; // Unverified - active: boolean; -} - -dayjs.extend(relativeTimePlugin); -dayjs.extend(utcPlugin); - -export const MonoField = (props: MonoFieldProps): JSX.Element => { - const { v, ...rest } = props; - return ( - - {v} - - ); -}; - -export const Active = (props: ActiveProps): JSX.Element => { - const { isActive } = props; - const color = useColorValue(['gray.500', 'green.500'], ['whiteAlpha.300', 'blackAlpha.500']); - return ( - - - - - - - - - ); -}; - -export const Age = (props: AgeProps): JSX.Element => { - const { inSeconds, ...rest } = props; - const now = dayjs.utc(); - const then = now.subtract(inSeconds, 'second'); - return ( - - - {now.to(then, true)} - - - ); -}; - -export const Weight = (props: WeightProps): JSX.Element => { - const { weight, winningWeight, ...rest } = props; - const fixMeText = - winningWeight === 'low' ? 'Lower Weight is Preferred' : 'Higher Weight is Preferred'; - return ( - - - {weight} - - - ); -}; - -export const ASPath = (props: ASPathProps): JSX.Element => { - const { path, active } = props; - const color = useColorValue( - // light: inactive, active - ['blackAlpha.500', 'blackAlpha.500'], - // dark: inactive, active - ['whiteAlpha.600', 'blackAlpha.700'], - ); - - if (path.length === 0) { - return ( - - - - - - ); - } - - const paths = [] as JSX.Element[]; - - path.map((asn, i) => { - const asnStr = String(asn); - i !== 0 && - paths.push( - , - ); - paths.push( - // biome-ignore lint/suspicious/noArrayIndexKey: index makes sense in this case. - - {asnStr} - , - ); - }); - - return {paths}; -}; - -export const Communities = (props: CommunitiesProps): JSX.Element => { - const { communities } = props; - const { web } = useConfig(); - const bg = useColorValue('white', 'gray.900'); - const color = useOpposingColor(bg); - return ( - - - - - - - - - - - - - - - {communities.join('\n')} - - - - - ); -}; - -const _RPKIState: React.ForwardRefRenderFunction = ( - props: RPKIStateProps, - ref, -) => { - const { state, active } = props; - const { web } = useConfig(); - const bg = useColorValue( - [ - ['red.400', 'green.500', 'yellow.400', 'gray.500'], - ['red.500', 'green.500', 'yellow.600', 'gray.600'], - ], - [ - ['red.300', 'green.300', 'yellow.300', 'gray.300'], - ['red.500', 'green.600', 'yellow.600', 'gray.800'], - ], - ); - const color = useOpposingColor(bg[+active][state]); - - const icon = [ - { md: 'MdCancel' }, - { fa: 'FaCheckCircle' }, - { bi: 'BiError' }, - { bs: 'BsQuestionCircleFill' }, - ] as Record[]; - - const text = [ - web.text.rpkiInvalid, - web.text.rpkiValid, - web.text.rpkiUnknown, - web.text.rpkiUnverified, - ]; - - return ( - - - - - - ); -}; - -export const RPKIState = forwardRef(_RPKIState); diff --git a/src/stale/hyperglass/hyperglass/ui/components/output/highlighted.tsx b/src/stale/hyperglass/hyperglass/ui/components/output/highlighted.tsx deleted file mode 100644 index e5f61c7..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/output/highlighted.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import { Badge, Tooltip, useStyleConfig } from '@chakra-ui/react'; -import React, { memo } from 'react'; -import isEqual from 'react-fast-compare'; -import replace from 'react-string-replace'; - -import type { TooltipProps } from '@chakra-ui/react'; -import type { Highlight as HighlightConfig } from '~/types'; - -interface HighlightedProps { - patterns: HighlightConfig[]; - children: string; -} - -interface HighlightProps { - label: string | null; - colorScheme: string; - children: React.ReactNode; -} - -const Highlight = (props: HighlightProps): JSX.Element => { - const { colorScheme, label, children } = props; - const { bg, color } = useStyleConfig('Button', { colorScheme }) as TooltipProps; - return ( - - {children} - - ); -}; - -const _Highlighted = (props: HighlightedProps): JSX.Element => { - const { patterns, children } = props; - let result: React.ReactNode[] = []; - let times: number = 0; - - if (patterns.length === 0) { - result = [children]; - } else { - for (const config of patterns) { - let toReplace: string | React.ReactNode[] = children; - if (times !== 0) { - toReplace = result; - } - result = replace(toReplace, new RegExp(`(${config.pattern})`, 'gm'), (m, i) => ( - - {m} - - )); - times++; - } - } - - return <>{result}; -}; - -export const Highlighted = memo(_Highlighted, isEqual); diff --git a/src/stale/hyperglass/hyperglass/ui/components/output/index.ts b/src/stale/hyperglass/hyperglass/ui/components/output/index.ts deleted file mode 100644 index 6e28bab..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/output/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './bgp-table'; -export * from './text-output'; diff --git a/src/stale/hyperglass/hyperglass/ui/components/output/text-output.tsx b/src/stale/hyperglass/hyperglass/ui/components/output/text-output.tsx deleted file mode 100644 index 1d2c821..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/output/text-output.tsx +++ /dev/null @@ -1,49 +0,0 @@ -import { Box } from '@chakra-ui/react'; -import { useConfig } from '~/context'; -import { useColorValue } from '~/hooks'; -import { Highlighted } from './highlighted'; - -import type { BoxProps } from '@chakra-ui/react'; - -type TextOutputProps = Swap; - -export const TextOutput = (props: TextOutputProps): JSX.Element => { - const { children, ...rest } = props; - - const bg = useColorValue('blackAlpha.100', 'gray.800'); - const color = useColorValue('black', 'white'); - const selectionBg = useColorValue('black', 'white'); - const selectionColor = useColorValue('white', 'black'); - - const { - web: { highlight }, - } = useConfig(); - - return ( - - - {children.split('\\n').join('\n').replace(/\n\n/g, '\n')} - - - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/path/chart.tsx b/src/stale/hyperglass/hyperglass/ui/components/path/chart.tsx deleted file mode 100644 index e5e95f3..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/path/chart.tsx +++ /dev/null @@ -1,99 +0,0 @@ -import { Badge, Box, Flex, SkeletonText, VStack } from '@chakra-ui/react'; -import { useMemo } from 'react'; -import ReactFlow, { - Background, - ReactFlowProvider, - Handle, - Position, - isNode, - isEdge, -} from 'reactflow'; -import { useConfig } from '~/context'; -import { useASNDetail, useColorToken, useColorValue } from '~/hooks'; -import { Controls } from './controls'; -import { useElements } from './use-elements'; - -import type { NodeProps as ReactFlowNodeProps } from 'reactflow'; - -interface ChartProps { - data: StructuredResponse; -} - -interface NodeProps extends Omit { - data: D; -} - -export interface NodeData { - asn: string; - name: string; - hasChildren: boolean; - hasParents?: boolean; -} - -export const Chart = (props: ChartProps): JSX.Element => { - const { data } = props; - const { primaryAsn, orgName } = useConfig(); - - const dots = useColorToken('colors', 'blackAlpha.500', 'whiteAlpha.400'); - - const elements = useElements({ asn: primaryAsn, name: orgName }, data); - - const nodes = useMemo(() => elements.filter(isNode), [elements]); - const edges = useMemo(() => elements.filter(isEdge), [elements]); - - return ( - - - setTimeout(() => inst.fitView(), 0)} - proOptions={{ hideAttribution: true }} - > - - - - - - ); -}; - -const ASNode = (props: NodeProps): JSX.Element => { - const { data } = props; - const { asn, name, hasChildren, hasParents } = data; - - const color = useColorValue('black', 'white'); - const bg = useColorValue('white', 'whiteAlpha.200'); - - const { data: asnData, isError, isLoading } = useASNDetail(String(asn)); - - return ( - <> - {hasChildren && } - - - - {isLoading ? ( - - - - ) : !isError && asnData?.data?.asn.organization?.orgName ? ( - asnData.data.asn.organization.orgName - ) : ( - name - )} - - - {asn} - - - - {hasParents && } - - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/path/controls.tsx b/src/stale/hyperglass/hyperglass/ui/components/path/controls.tsx deleted file mode 100644 index eb0949d..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/path/controls.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import { ButtonGroup, IconButton } from '@chakra-ui/react'; -import { useReactFlow } from 'reactflow'; -import { DynamicIcon } from '~/elements'; - -export const Controls = (): JSX.Element => { - const { fitView, zoomIn, zoomOut } = useReactFlow(); - return ( - - } - onClick={() => zoomIn()} - aria-label="Zoom In" - /> - } - onClick={() => zoomOut()} - aria-label="Zoom Out" - /> - } - onClick={() => fitView()} - aria-label="Fit Nodes" - /> - - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/path/index.ts b/src/stale/hyperglass/hyperglass/ui/components/path/index.ts deleted file mode 100644 index 44bb0aa..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/path/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './path'; diff --git a/src/stale/hyperglass/hyperglass/ui/components/path/path-button.tsx b/src/stale/hyperglass/hyperglass/ui/components/path/path-button.tsx deleted file mode 100644 index 4b1d121..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/path/path-button.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { Button, Tooltip } from '@chakra-ui/react'; -import { DynamicIcon } from '~/elements'; - -interface PathButtonProps { - onOpen(): void; -} - -export const PathButton = (props: PathButtonProps): JSX.Element => { - const { onOpen } = props; - return ( - - - - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/path/path.tsx b/src/stale/hyperglass/hyperglass/ui/components/path/path.tsx deleted file mode 100644 index 0fd3d74..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/path/path.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import { - Modal, - ModalBody, - ModalCloseButton, - ModalContent, - ModalHeader, - ModalOverlay, - Skeleton, - useDisclosure, -} from '@chakra-ui/react'; -import 'reactflow/dist/style.css'; -import { useBreakpointValue, useColorValue, useFormState } from '~/hooks'; -import { Chart } from './chart'; -import { PathButton } from './path-button'; - -interface PathProps { - device: string; -} - -export const Path = (props: PathProps): JSX.Element => { - const { device } = props; - const displayTarget = useFormState(s => s.target.display); - const getResponse = useFormState(s => s.response); - const { isOpen, onClose, onOpen } = useDisclosure(); - const response = getResponse(device); - const output = response?.output as StructuredResponse; - const bg = useColorValue('light.50', 'dark.900'); - const centered = useBreakpointValue({ base: false, lg: true }) ?? true; - return ( - <> - - - - - {`Path to ${displayTarget}`} - - - - - - - - - - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/path/use-elements.ts b/src/stale/hyperglass/hyperglass/ui/components/path/use-elements.ts deleted file mode 100644 index d7b107b..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/path/use-elements.ts +++ /dev/null @@ -1,125 +0,0 @@ -import dagre from 'dagre'; -import { useMemo } from 'react'; -import isEqual from 'react-fast-compare'; - -import type { Edge, Node } from 'reactflow'; -import type { NodeData } from './chart'; - -interface BasePath { - asn: string; - name: string; -} - -type FlowElement = Node | Edge; - -const NODE_WIDTH = 128; -const NODE_HEIGHT = 48; - -export function useElements(base: BasePath, data: StructuredResponse): FlowElement[] { - return useMemo(() => { - return [...buildElements(base, data)]; - }, [base, data]); -} - -/** - * Calculate the positions for each AS Path. - * @see https://github.com/MrBlenny/react-flow-chart/issues/61 - */ -function* buildElements( - base: BasePath, - data: StructuredResponse, -): Generator> { - const { routes } = data; - // Eliminate empty AS paths & deduplicate non-empty AS paths. Length should be same as count minus empty paths. - const asPaths = routes.filter(r => r.as_path.length !== 0).map(r => [...new Set(r.as_path)]); - - const totalPaths = asPaths.length - 1; - - const g = new dagre.graphlib.Graph(); - g.setGraph({ marginx: 20, marginy: 20 }); - g.setDefaultEdgeLabel(() => ({})); - - // Set the origin (i.e., the hyperglass user) at the base. - g.setNode(base.asn, { width: NODE_WIDTH, height: NODE_HEIGHT }); - - for (const [groupIdx, pathGroup] of asPaths.entries()) { - // For each ROUTE's AS Path: - - // Find the route after this one. - const nextGroup = groupIdx < totalPaths ? asPaths[groupIdx + 1] : []; - - // Connect the first hop in the AS Path to the base (for dagre). - g.setEdge(base.asn, `${groupIdx}-${pathGroup[0]}`); - - // Eliminate duplicate AS Paths. - if (!isEqual(pathGroup, nextGroup)) { - for (const [idx, asn] of pathGroup.entries()) { - // For each ASN in the ROUTE: - - const node = `${groupIdx}-${asn}`; - const endIdx = pathGroup.length - 1; - - // Add the AS as a node. - g.setNode(node, { width: NODE_WIDTH, height: NODE_HEIGHT }); - - // Connect the first hop in the AS Path to the base (for react-flow). - if (idx === 0) { - yield { - id: `e${base.asn}-${node}`, - source: base.asn, - target: node, - }; - } - // Connect every intermediate hop to each other. - if (idx !== endIdx) { - const next = `${groupIdx}-${pathGroup[idx + 1]}`; - g.setEdge(node, next); - yield { - id: `e${node}-${next}`, - source: node, - target: next, - }; - } - } - } - } - - // Now that that nodes are added, create the layout. - dagre.layout(g, { rankdir: 'BT', align: 'UR' }); - - // Get the base ASN's positions. - const x = g.node(base.asn).x - NODE_WIDTH / 2; - const y = g.node(base.asn).y + NODE_HEIGHT * 6; - - yield { - id: base.asn, - type: 'ASNode', - position: { x, y }, - data: { asn: base.asn, name: base.name, hasChildren: true, hasParents: false }, - }; - - for (const [groupIdx, pathGroup] of asPaths.entries()) { - const nextGroup = groupIdx < totalPaths ? asPaths[groupIdx + 1] : []; - if (!isEqual(pathGroup, nextGroup)) { - for (const [idx, asn] of pathGroup.entries()) { - const node = `${groupIdx}-${asn}`; - const endIdx = pathGroup.length - 1; - const x = g.node(node).x - NODE_WIDTH / 2; - const y = g.node(node).y - NODE_HEIGHT * (idx * 6); - - // Get each ASN's positions. - yield { - id: node, - type: 'ASNode', - position: { x, y }, - data: { - asn: `${asn}`, - name: `AS${asn}`, - hasChildren: idx < endIdx, - hasParents: true, - }, - }; - } - } - } -} diff --git a/src/stale/hyperglass/hyperglass/ui/components/prompt/desktop.tsx b/src/stale/hyperglass/hyperglass/ui/components/prompt/desktop.tsx deleted file mode 100644 index e9cdd1c..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/prompt/desktop.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { - Popover, - PopoverBody, - PopoverArrow, - PopoverTrigger, - PopoverContent, - PopoverCloseButton, -} from '@chakra-ui/react'; -import { useColorValue } from '~/hooks'; - -import type { PromptProps } from './types'; - -export const DesktopPrompt = (props: PromptProps): JSX.Element => { - const { trigger, children, ...disclosure } = props; - const bg = useColorValue('white', 'gray.900'); - - return ( - - {trigger} - - - - {children} - - - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/prompt/index.tsx b/src/stale/hyperglass/hyperglass/ui/components/prompt/index.tsx deleted file mode 100644 index 1f50f6d..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/prompt/index.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { useMobile } from '~/hooks'; -import { DesktopPrompt } from './desktop'; -import { MobilePrompt } from './mobile'; - -import type { PromptProps } from './types'; - -export const Prompt = (props: PromptProps): JSX.Element => { - const isMobile = useMobile(); - - return isMobile ? : ; -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/prompt/mobile.tsx b/src/stale/hyperglass/hyperglass/ui/components/prompt/mobile.tsx deleted file mode 100644 index 47c0da5..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/prompt/mobile.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import { Modal, ModalBody, ModalOverlay, ModalContent, ModalCloseButton } from '@chakra-ui/react'; -import { useColorValue } from '~/hooks'; - -import type { PromptProps } from './types'; - -export const MobilePrompt = (props: PromptProps): JSX.Element => { - const { children, trigger, ...disclosure } = props; - const bg = useColorValue('white', 'gray.900'); - return ( - <> - {trigger} - - - - - - {children} - - - - - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/prompt/types.ts b/src/stale/hyperglass/hyperglass/ui/components/prompt/types.ts deleted file mode 100644 index 9c32b10..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/prompt/types.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { UseDisclosureReturn } from '@chakra-ui/react'; - -type PromptPropsBase = React.PropsWithChildren< - Omit, 'isOpen' | 'onClose'> & - Pick ->; - -export interface PromptProps extends PromptPropsBase { - trigger?: JSX.Element; -} diff --git a/src/stale/hyperglass/hyperglass/ui/components/query-location.tsx b/src/stale/hyperglass/hyperglass/ui/components/query-location.tsx deleted file mode 100644 index c8f040f..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/query-location.tsx +++ /dev/null @@ -1,181 +0,0 @@ -import { Flex, Stack, Wrap, chakra } from '@chakra-ui/react'; -import { useMemo } from 'react'; -import { useFormContext } from 'react-hook-form'; -import { LocationCard, Select } from '~/components'; -import { isMultiValue, isSingleValue } from '~/components/select'; -import { useConfig } from '~/context'; -import { useFormState } from '~/hooks'; - -import type { SelectOnChange } from '~/components/select'; -import type { DeviceGroup, FormData, OnChangeArgs, OptionGroup, SingleOption } from '~/types'; - -/** Location option type alias for future extensions. */ -export type LocationOption = SingleOption; - -interface QueryLocationProps { - onChange: (f: OnChangeArgs) => void; - label: string; -} - -function buildOptions(devices: DeviceGroup[]): OptionGroup[] { - return devices - .map(group => { - const label = group.group; - const options = group.locations - .map( - loc => - ({ - label: loc.name, - value: loc.id, - group: loc.group, - data: { - avatar: loc.avatar, - description: loc.description, - }, - }) as SingleOption, - ) - .sort((a, b) => (a.label < b.label ? -1 : a.label > b.label ? 1 : 0)); - return { label: label ?? '', options }; - }) - .sort((a, b) => - (a.label ?? 0) < (b.label ?? 0) ? -1 : (a.label ?? 0) > (b.label ?? 0) ? 1 : 0, - ); -} - -export const QueryLocation = (props: QueryLocationProps): JSX.Element => { - const { onChange, label } = props; - - const { - devices, - web: { locationDisplayMode }, - } = useConfig(); - const { - formState: { errors }, - } = useFormContext(); - const selections = useFormState(s => s.selections); - const setSelection = useFormState(s => s.setSelection); - const { form, filtered } = useFormState(({ form, filtered }) => ({ form, filtered })); - const options = useMemo(() => buildOptions(devices), [devices]); - - const element = useMemo(() => { - if (locationDisplayMode === 'dropdown') { - return 'select'; - } - if (locationDisplayMode === 'gallery') { - return 'cards'; - } - const groups = options.length; - const maxOptionsPerGroup = Math.max(...options.map(opt => opt.options.length)); - const showCards = groups < 5 && maxOptionsPerGroup < 9; - return showCards ? 'cards' : 'select'; - }, [options, locationDisplayMode]); - - const noOverlap = useMemo( - () => form.queryLocation.length > 1 && filtered.types.length === 0, - [form, filtered], - ); - - /** - * Update form and state when a card selections change. - * - * @param action Add or remove the option. - * @param option Full option object. - */ - function handleCardChange(action: 'add' | 'remove', option: SingleOption) { - const exists = selections.queryLocation.map(q => q.value).includes(option.value); - if (action === 'add' && !exists) { - const toAdd = [...form.queryLocation, option.value]; - const newSelections = [...selections.queryLocation, option]; - setSelection('queryLocation', newSelections); - onChange({ field: 'queryLocation', value: toAdd }); - } else if (action === 'remove' && exists) { - const index = selections.queryLocation.findIndex(v => v.value === option.value); - const toRemove = [...form.queryLocation.filter(v => v !== option.value)]; - setSelection( - 'queryLocation', - selections.queryLocation.filter((_, i) => i !== index), - ); - onChange({ field: 'queryLocation', value: toRemove }); - } - } - - /** - * Update form and state when select element values change. - * - * @param options Final value. React-select determines if an option is being added or removed and - * only sends back the final value. - */ - const handleSelectChange: SelectOnChange = (options): void => { - if (isMultiValue(options)) { - onChange({ field: 'queryLocation', value: options.map(o => o.value) }); - setSelection('queryLocation', options); - } else if (isSingleValue(options)) { - onChange({ field: 'queryLocation', value: options.value }); - setSelection('queryLocation', [options]); - } - }; - - if (element === 'cards') { - return ( - <> - {options.length === 1 ? ( - - {options[0].options.map(opt => { - return ( - - ); - })} - - ) : ( - <> - {options.map(group => ( - - - {group.label} - - {group.options.map(opt => { - return ( - - ); - })} - - ))} - - )} - - ); - } - if (element === 'select') { - return ( - - isMulti - options={options} - aria-label={label} - name="queryLocation" - closeMenuOnSelect={true} - onChange={handleSelectChange} - value={selections.queryLocation} - isError={typeof errors.queryLocation !== 'undefined'} - /> - ); - } - return No Locations; -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/query-target.tsx b/src/stale/hyperglass/hyperglass/ui/components/query-target.tsx deleted file mode 100644 index 1d452f9..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/query-target.tsx +++ /dev/null @@ -1,113 +0,0 @@ -import { Input, InputGroup, InputRightElement, Text } from '@chakra-ui/react'; -import { useMemo } from 'react'; -import { components } from 'react-select'; -import { Select } from '~/components'; -import { isSingleValue } from '~/components/select'; -import { useDirective, useFormState } from '~/hooks'; -import { isSelectDirective } from '~/types'; -import { UserIP } from './user-ip'; - -import { type UseFormRegister, useForm } from 'react-hook-form'; -import type { GroupBase, OptionProps } from 'react-select'; -import type { SelectOnChange } from '~/components/select'; -import type { Directive, FormData, OnChangeArgs, SingleOption } from '~/types'; - -type OptionWithDescription = SingleOption<{ description: string | null }>; - -interface QueryTargetProps { - name: string; - placeholder: string; - onChange(e: OnChangeArgs): void; - register: UseFormRegister; -} - -function buildOptions(directive: Nullable): OptionWithDescription[] { - if (directive !== null && isSelectDirective(directive)) { - return directive.options.map(o => ({ - value: o.value, - label: o.name, - data: { description: o.description }, - })); - } - return []; -} - -const Option = (props: OptionProps) => { - const { label, data } = props; - return ( - > {...props}> - {label} -
- - {data.data?.description} - - - ); -}; - -export const QueryTarget = (props: QueryTargetProps): JSX.Element => { - const { name, register, onChange, placeholder } = props; - - const displayTarget = useFormState(s => s.target.display); - const setTarget = useFormState(s => s.setTarget); - const queryTarget = useFormState(s => s.form.queryTarget); - const directive = useDirective(); - - const options = useMemo(() => buildOptions(directive), [directive]); - const isSelect = useMemo(() => directive !== null && isSelectDirective(directive), [directive]); - - function handleInputChange(e: React.ChangeEvent): void { - setTarget({ display: e.target.value }); - onChange({ field: name, value: [e.target.value] }); - } - - const handleSelectChange: SelectOnChange = e => { - if (isSingleValue(e)) { - onChange({ field: name, value: e.value }); - setTarget({ display: e.value }); - } - }; - - const handleUserIPChange = (target: string): void => { - setTarget({ display: target }); - onChange({ field: name, value: target }); - }; - - return ( - <> - - {isSelect ? ( - - name={name} - options={options} - components={{ Option }} - onChange={handleSelectChange} - /> - ) : ( - - - - - - - )} - - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/query-type.tsx b/src/stale/hyperglass/hyperglass/ui/components/query-type.tsx deleted file mode 100644 index 7b9ac73..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/query-type.tsx +++ /dev/null @@ -1,185 +0,0 @@ -import { useMemo } from 'react'; -import create from 'zustand'; -import { Box, Button, HStack, useRadio, useRadioGroup } from '@chakra-ui/react'; -import { useFormContext } from 'react-hook-form'; -import { components } from 'react-select'; -import { Select } from '~/components'; -import { useFormState, useFormSelections } from '~/hooks'; -import { isSingleValue } from '~/components/select'; - -import type { UseRadioProps } from '@chakra-ui/react'; -import type { MenuListProps } from 'react-select'; -import type { SingleOption, OptionGroup, OptionsOrGroup, OnChangeArgs } from '~/types'; -import type { SelectOnChange } from '~/components/select'; - -type QueryTypeOption = SingleOption<{ group?: string }>; - -interface QueryTypeProps { - onChange: (f: OnChangeArgs) => void; - label: string; -} - -type UserFilter = { - selected: string; - setSelected(n: string): void; - filter(candidate: QueryTypeOption, input: string): boolean; -}; - -function sorter>(a: T, b: T): number { - return a.label < b.label ? -1 : a.label > b.label ? 1 : 0; -} - -const useFilter = create((set, get) => ({ - selected: '', - setSelected(newValue: string) { - set(() => ({ selected: newValue })); - }, - filter(candidate, input): boolean { - const { label, data } = candidate; - const group = data?.group ?? null; - - if (input && (label || group)) { - const search = input.toLowerCase(); - if (group) { - return label.toLowerCase().indexOf(search) > -1 || group.toLowerCase().indexOf(search) > -1; - } - return label.toLowerCase().indexOf(search) > -1; - } - const { selected } = get(); - if (selected !== '' && selected === group) { - return true; - } - if (selected === '') { - return true; - } - return false; - }, -})); - -function useOptions() { - const filtered = useFormState(s => s.filtered); - return useMemo((): OptionsOrGroup => { - const groupNames = new Set( - filtered.types.filter(t => t.groups.length > 0).flatMap(t => t.groups), - ); - const optGroups: OptionGroup[] = Array.from(groupNames).map(group => ({ - label: group, - options: filtered.types - .filter(t => t.groups.includes(group)) - .map(t => ({ label: t.name, value: t.id, group })) - .sort(sorter), - })); - - const noGroups: OptionGroup = { - label: '', - options: filtered.types - .filter(t => t.groups.length === 0) - .map(t => ({ label: t.name, value: t.id, group: '' })) - .sort(sorter), - }; - - return [noGroups, ...optGroups].sort(sorter); - }, [filtered.types]); -} - -const GroupFilter = (props: React.PropsWithChildren): JSX.Element => { - const { children, ...rest } = props; - const { - getInputProps, - getCheckboxProps, - getLabelProps, - htmlProps, - state: { isChecked }, - } = useRadio(rest); - const label = getLabelProps(); - const input = getInputProps(); - const checkbox = getCheckboxProps(); - - return ( - - - - - ); -}; - -const MenuList = (props: MenuListProps): JSX.Element => { - const { children, ...rest } = props; - const filtered = useFormState(s => s.filtered); - const selected = useFilter(state => state.selected); - const setSelected = useFilter(state => state.setSelected); - - const { getRadioProps, getRootProps } = useRadioGroup({ - name: 'queryGroup', - value: selected, - }); - - function handleClick(value: string): void { - setSelected(value); - } - return ( - - - handleClick('') })}> - None - - {filtered.groups.map(value => { - return ( - handleClick(value) })} - > - {value} - - ); - })} - - {children} - - ); -}; - -export const QueryType = (props: QueryTypeProps): JSX.Element => { - const { onChange, label } = props; - const { - formState: { errors }, - } = useFormContext(); - const setSelection = useFormState(s => s.setSelection); - const selections = useFormSelections(); - const setFormValue = useFormState(s => s.setFormValue); - const options = useOptions(); - const { filter } = useFilter(); // Intentionally re-render on any changes - - const handleChange: SelectOnChange = e => { - let value = ''; - if (isSingleValue(e)) { - setSelection('queryType', e); - value = e.value; - } else { - setFormValue('queryType', ''); - setSelection('queryType', null); - } - onChange({ field: 'queryType', value }); - }; - - return ( - - name="queryType" - options={options} - aria-label={label} - filterOption={filter} - onChange={handleChange} - components={{ MenuList }} - isError={'queryType' in errors} - value={selections.queryType} - /> - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/reset-button.tsx b/src/stale/hyperglass/hyperglass/ui/components/reset-button.tsx deleted file mode 100644 index c0ea69f..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/reset-button.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import { Flex, IconButton } from '@chakra-ui/react'; -import { AnimatePresence } from 'framer-motion'; -import { AnimatedDiv, DynamicIcon } from '~/elements'; -import { useColorValue, useOpposingColor, useFormState } from '~/hooks'; - -import type { FlexProps } from '@chakra-ui/react'; - -interface ResetButtonProps extends FlexProps { - developerMode: boolean; - resetForm(): void; -} - -export const ResetButton = (props: ResetButtonProps): JSX.Element => { - const { developerMode, resetForm, ...rest } = props; - const status = useFormState(s => s.status); - const bg = useColorValue('primary.500', 'primary.300'); - const color = useOpposingColor(bg); - return ( - - {status === 'results' && ( - - - } - /> - - - )} - - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/resolved-target.tsx b/src/stale/hyperglass/hyperglass/ui/components/resolved-target.tsx deleted file mode 100644 index 9130d6e..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/resolved-target.tsx +++ /dev/null @@ -1,138 +0,0 @@ -import { useMemo } from 'react'; -import { Button, Stack, Text, VStack } from '@chakra-ui/react'; -import { useConfig } from '~/context'; -import { DynamicIcon } from '~/elements'; -import { useStrf, useColorValue, useDNSQuery, useFormState } from '~/hooks'; - -import type { DnsOverHttps } from '~/types'; - -interface ResolvedTargetProps { - errorClose(): void; -} - -function findAnswer(data: DnsOverHttps.Response | undefined): string { - let answer = ''; - if (typeof data !== 'undefined') { - answer = data?.Answer?.filter(answerData => answerData.type === data?.Question[0]?.type)[0] - ?.data; - } - return answer; -} - -export const ResolvedTarget = (props: ResolvedTargetProps): JSX.Element => { - const { errorClose } = props; - const strF = useStrf(); - const { web } = useConfig(); - - const setStatus = useFormState(s => s.setStatus); - const displayTarget = useFormState(s => s.target.display); - const setFormValue = useFormState(s => s.setFormValue); - - const color = useColorValue('secondary.500', 'secondary.300'); - const errorColor = useColorValue('red.500', 'red.300'); - - const tooltip4 = strF(web.text.fqdnTooltip, { protocol: 'IPv4' }); - const tooltip6 = strF(web.text.fqdnTooltip, { protocol: 'IPv6' }); - - const [messageStart, messageEnd] = web.text.fqdnMessage.split('{fqdn}'); - const [errorStart, errorEnd] = web.text.fqdnError.split('{fqdn}'); - - const { - data: data4, - isLoading: isLoading4, - isError: isError4, - error: error4, - } = useDNSQuery(displayTarget, 4); - - const { - data: data6, - isLoading: isLoading6, - isError: isError6, - error: error6, - } = useDNSQuery(displayTarget, 6); - - isError4 && console.error(error4); - isError6 && console.error(error6); - - const answer4 = useMemo(() => findAnswer(data4), [data4]); - const answer6 = useMemo(() => findAnswer(data6), [data6]); - - function selectTarget(value: string): void { - setFormValue('queryTarget', [value]); - setStatus('results'); - } - - const hasAnswer = useMemo( - () => (!isError4 || !isError6) && (answer4 || answer6), - [answer4, answer6, isError4, isError6], - ); - const showA = useMemo(() => !isLoading4 && !isError4 && answer4, [isLoading4, isError4, answer4]); - const showAAAA = useMemo( - () => !isLoading6 && !isError6 && answer6, - [isLoading6, isError6, answer6], - ); - - return ( - - {hasAnswer && ( - - {messageStart} - - {`${displayTarget}`.toLowerCase()} - - {messageEnd} - - )} - - {showA && ( - - )} - {showAAAA && ( - - )} - {!hasAnswer && ( - <> - - {errorStart} - - {`${displayTarget}`.toLowerCase()} - - {errorEnd} - - - - )} - - - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/results/copy-button.tsx b/src/stale/hyperglass/hyperglass/ui/components/results/copy-button.tsx deleted file mode 100644 index fddd87e..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/results/copy-button.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { Button, Tooltip, useClipboard } from '@chakra-ui/react'; -import { DynamicIcon } from '~/elements'; - -import type { ButtonProps } from '@chakra-ui/react'; - -interface CopyButtonProps extends ButtonProps { - copyValue: string; -} - -export const CopyButton = (props: CopyButtonProps): JSX.Element => { - const { copyValue, ...rest } = props; - const { onCopy, hasCopied } = useClipboard(copyValue); - return ( - - - - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/results/formatted-error.tsx b/src/stale/hyperglass/hyperglass/ui/components/results/formatted-error.tsx deleted file mode 100644 index 6070151..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/results/formatted-error.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { chakra } from '@chakra-ui/react'; - -interface FormattedErrorProps { - keywords: string[]; - message: string; -} - -type FormatError = string | JSX.Element; - -function formatError(text: string, values: string[], regex: RegExp): FormatError[] | FormatError { - if (!values.length) { - return text; - } - - const parts = text.split(regex); - - return parts.reduce((prev, current, i) => { - if (!i) { - return [current]; - } - - return prev.concat( - values.includes(current) ? {current} : current, - ); - }, [] as FormatError[]); -} - -export const FormattedError = (props: FormattedErrorProps): JSX.Element => { - const { keywords, message } = props; - const pattern = new RegExp(keywords.map(kw => `(${kw})`).join('|'), 'gi'); - const things = formatError(message, keywords, pattern); - return ( - - {keywords.length !== 0 ? things : message} - - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/results/group.tsx b/src/stale/hyperglass/hyperglass/ui/components/results/group.tsx deleted file mode 100644 index 2b032d2..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/results/group.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import { Accordion } from '@chakra-ui/react'; -import { AnimatePresence } from 'framer-motion'; -import { useEffect } from 'react'; -import { AnimatedDiv } from '~/elements'; -import { useFormState } from '~/hooks'; -import { Result } from './individual'; -import { Tags } from './tags'; - -export const Results = (): JSX.Element => { - const { queryLocation } = useFormState(s => s.form); - - // Scroll to the top of the page when results load - primarily for mobile. - useEffect(() => { - if (typeof window !== 'undefined') { - window.scrollTo(0, 0); - } - }, []); - - return ( - <> - - - - - {queryLocation.length > 0 && - queryLocation.map((location, index) => { - return ; - })} - - - - - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/results/guards.ts b/src/stale/hyperglass/hyperglass/ui/components/results/guards.ts deleted file mode 100644 index a70b6f0..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/results/guards.ts +++ /dev/null @@ -1,22 +0,0 @@ -// biome-ignore lint/suspicious/noExplicitAny: type guard -export function isStackError(error: any): error is Error { - return typeof error !== 'undefined' && error !== null && 'message' in error; -} - -// biome-ignore lint/suspicious/noExplicitAny: type guard -export function isFetchError(error: any): error is Response { - return typeof error !== 'undefined' && error !== null && 'statusText' in error; -} - -// biome-ignore lint/suspicious/noExplicitAny: type guard -export function isLGError(error: any): error is QueryResponse { - return typeof error !== 'undefined' && error !== null && 'output' in error; -} - -/** - * Returns true if the response is an LG error, false if not. - */ -// biome-ignore lint/suspicious/noExplicitAny: type guard -export function isLGOutputOrError(data: any): data is QueryResponse { - return typeof data !== 'undefined' && data !== null && data?.level !== 'success'; -} diff --git a/src/stale/hyperglass/hyperglass/ui/components/results/header.tsx b/src/stale/hyperglass/hyperglass/ui/components/results/header.tsx deleted file mode 100644 index f82a62a..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/results/header.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import { AccordionIcon, Box, HStack, Spinner, Text, Tooltip } from '@chakra-ui/react'; -import { useMemo } from 'react'; -import { useConfig } from '~/context'; -import { DynamicIcon } from '~/elements'; -import { useColorValue, useOpposingColor, useStrf } from '~/hooks'; - -import type { ErrorLevels } from '~/types'; - -interface ResultHeaderProps { - title: string; - loading: boolean; - isError?: boolean; - errorMsg: string; - errorLevel: ErrorLevels; - runtime: number; -} - -const runtimeText = (runtime: number, text: string): string => { - let unit = 'seconds'; - if (runtime === 1) { - unit = 'second'; - } - return `${text} ${unit}`; -}; - -export const ResultHeader = (props: ResultHeaderProps): JSX.Element => { - const { title, loading, isError, errorMsg, errorLevel, runtime } = props; - - const status = useColorValue('primary.500', 'primary.300'); - const warning = useColorValue(`${errorLevel}.500`, `${errorLevel}.300`); - const defaultStatus = useColorValue('success.500', 'success.300'); - - const { web } = useConfig(); - const strF = useStrf(); - const text = strF(web.text.completeTime, { seconds: runtime }); - const label = useMemo(() => runtimeText(runtime, text), [runtime, text]); - - const color = useOpposingColor(isError ? warning : defaultStatus); - - return ( - - - - {loading ? ( - - ) : ( - - )} - - - - {title} - - - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/results/index.ts b/src/stale/hyperglass/hyperglass/ui/components/results/index.ts deleted file mode 100644 index 8a78f59..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/results/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './group'; diff --git a/src/stale/hyperglass/hyperglass/ui/components/results/individual.tsx b/src/stale/hyperglass/hyperglass/ui/components/results/individual.tsx deleted file mode 100644 index a316dd3..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/results/individual.tsx +++ /dev/null @@ -1,307 +0,0 @@ -import { - AccordionButton, - AccordionItem, - AccordionPanel, - Alert, - Box, - Flex, - HStack, - Tooltip, - chakra, - useAccordionContext, - useToast, -} from '@chakra-ui/react'; -import { motion } from 'framer-motion'; -import startCase from 'lodash/startCase'; -import { forwardRef, memo, useEffect, useMemo, useState } from 'react'; -import isEqual from 'react-fast-compare'; -import { Else, If, Then } from 'react-if'; -import { BGPTable, Path, TextOutput } from '~/components'; -import { useConfig } from '~/context'; -import { Countdown, DynamicIcon } from '~/elements'; -import { - useColorValue, - useDevice, - useFormState, - useLGQuery, - useMobile, - useStrf, - useTableToString, -} from '~/hooks'; -import { isStringOutput, isStructuredOutput } from '~/types'; -import { CopyButton } from './copy-button'; -import { FormattedError } from './formatted-error'; -import { isFetchError, isLGError, isLGOutputOrError, isStackError } from './guards'; -import { ResultHeader } from './header'; -import { RequeryButton } from './requery-button'; - -import type { ErrorLevels } from '~/types'; - -interface ResultProps { - index: number; - queryLocation: string; -} - -const AnimatedAccordionItem = motion(AccordionItem); - -const AccordionHeaderWrapper = chakra('div', { - baseStyle: { - display: 'flex', - justifyContent: 'space-between', - _hover: { bg: 'blackAlpha.50' }, - _focus: { boxShadow: 'outline' }, - }, -}); - -const _Result: React.ForwardRefRenderFunction = ( - props: ResultProps, - ref, -) => { - const { index, queryLocation } = props; - const toast = useToast(); - const { web, cache, messages } = useConfig(); - const { index: indices, setIndex } = useAccordionContext(); - const getDevice = useDevice(); - const device = getDevice(queryLocation); - - const isMobile = useMobile(); - const color = useColorValue('black', 'white'); - const scrollbar = useColorValue('blackAlpha.300', 'whiteAlpha.300'); - const scrollbarHover = useColorValue('blackAlpha.400', 'whiteAlpha.400'); - const scrollbarBg = useColorValue('blackAlpha.50', 'whiteAlpha.50'); - - const addResponse = useFormState(s => s.addResponse); - const form = useFormState(s => s.form); - const [errorLevel, _setErrorLevel] = useState('error'); - - const setErrorLevel = (level: ResponseLevel): void => { - let e: ErrorLevels = 'error'; - switch (level) { - case 'success': - e = level; - break; - case 'warning' || 'error': - e = 'warning'; - break; - } - _setErrorLevel(e); - }; - - const { data, error, isLoading, refetch, isFetchedAfterMount } = useLGQuery( - { queryLocation, queryTarget: form.queryTarget, queryType: form.queryType }, - { - onSuccess(data) { - if (device !== null) { - addResponse(device.id, data); - } - if (isLGOutputOrError(data)) { - console.error(data); - setErrorLevel(data.level); - } - }, - onError(error) { - console.error({ error }); - if (isLGOutputOrError(error)) { - setErrorLevel(error.level); - } - }, - }, - ); - - const isError = useMemo(() => isLGOutputOrError(data), [data, error]); - - const isCached = useMemo(() => data?.cached || !isFetchedAfterMount, [data, isFetchedAfterMount]); - - const strF = useStrf(); - const cacheLabel = strF(web.text.cacheIcon, { time: data?.timestamp }); - - const errorKeywords = useMemo(() => { - let kw = [] as string[]; - if (isLGError(data)) { - kw = data.keywords; - } - return kw; - }, [data]); - - // Parse the the response and/or the error to determine from where to extract the error message. - const errorMsg = useMemo(() => { - if (isLGError(error)) { - return error.output as string; - } - if (isLGOutputOrError(data)) { - return data.output as string; - } - if (isFetchError(error)) { - return startCase(error.statusText); - } - if (isStackError(error) && error.message.toLowerCase().startsWith('timeout')) { - return messages.requestTimeout; - } - if (isStackError(error)) { - return startCase(error.message); - } - return messages.general; - }, [error, data, messages.general, messages.requestTimeout]); - - const tableComponent = useMemo(() => { - let result = false; - if (data?.format === 'application/json') { - result = true; - } - return result; - }, [data?.format]); - - let copyValue = data?.output as string; - - const formatData = useTableToString(form.queryTarget, data, [data?.format]); - - if (data?.format === 'application/json') { - copyValue = formatData(); - } - - if (error) { - copyValue = errorMsg; - } - - // Signal to the group that this result is done loading. - useEffect(() => { - // Only set the index if it's not already set and the query is finished loading. - if (Array.isArray(indices) && indices.length === 0 && !isLoading) { - // Only set the index if the response has data or an error. - if (data || isError) { - setIndex([index]); - } - } - }, [data, index, indices, isLoading, isError, setIndex]); - - if (device === null) { - const id = `toast-queryLocation-${index}-${queryLocation}`; - if (!toast.isActive(id)) { - toast({ - id, - title: messages.general, - description: `Configuration for device with ID '${queryLocation}' not found.`, - status: 'error', - isClosable: true, - }); - } - return <>; - } - - return ( - - - - - - - {isStructuredOutput(data) && data.level === 'success' && tableComponent && ( - - )} - - - - - - - - - - {isStructuredOutput(data) && data.level === 'success' && tableComponent ? ( - {data.output} - ) : isStringOutput(data) && data.level === 'success' && !tableComponent ? ( - {data.output} - ) : isStringOutput(data) && data.level !== 'success' ? ( - - - - ) : ( - - - - )} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ); -}; - -export const Result = memo(forwardRef(_Result), isEqual); diff --git a/src/stale/hyperglass/hyperglass/ui/components/results/requery-button.tsx b/src/stale/hyperglass/hyperglass/ui/components/results/requery-button.tsx deleted file mode 100644 index 7df11cb..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/results/requery-button.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { forwardRef } from 'react'; -import { Button, Tooltip } from '@chakra-ui/react'; -import { DynamicIcon } from '~/elements'; - -import type { ButtonProps } from '@chakra-ui/react'; -import type { UseQueryResult } from '@tanstack/react-query'; - -interface RequeryButtonProps extends ButtonProps { - requery: Get, 'refetch'>; -} - -const _RequeryButton: React.ForwardRefRenderFunction = ( - props: RequeryButtonProps, - ref, -) => { - const { requery, ...rest } = props; - - return ( - - - - ); -}; - -export const RequeryButton = forwardRef(_RequeryButton); diff --git a/src/stale/hyperglass/hyperglass/ui/components/results/tags.tsx b/src/stale/hyperglass/hyperglass/ui/components/results/tags.tsx deleted file mode 100644 index d03c9a3..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/results/tags.tsx +++ /dev/null @@ -1,98 +0,0 @@ -import { useMemo } from 'react'; -import { Box, Stack, useToken } from '@chakra-ui/react'; -import { motion, AnimatePresence } from 'framer-motion'; -import { useConfig } from '~/context'; -import { Label } from '~/elements'; -import { useFormState, useBreakpointValue } from '~/hooks'; - -import type { Transition } from 'framer-motion'; - -const transition = { duration: 0.3, delay: 0.5 } as Transition; - -export const Tags = (): JSX.Element => { - const { web } = useConfig(); - const form = useFormState(s => s.form); - const getDirective = useFormState(s => s.getDirective); - - const selectedDirective = useMemo(() => { - return getDirective(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [form.queryType, getDirective]); - - const targetBg = useToken('colors', 'teal.600'); - const queryBg = useToken('colors', 'cyan.500'); - - const animateLeft = useBreakpointValue({ - base: { opacity: 1, x: 0 }, - md: { opacity: 1, x: 0 }, - lg: { opacity: 1, x: 0 }, - xl: { opacity: 1, x: 0 }, - }); - - const animateRight = useBreakpointValue({ - base: { opacity: 1, x: 0 }, - md: { opacity: 1, x: 0 }, - lg: { opacity: 1, x: 0 }, - xl: { opacity: 1, x: 0 }, - }); - - const initialLeft = useBreakpointValue({ - base: { opacity: 0, x: '-100%' }, - md: { opacity: 0, x: '-100%' }, - lg: { opacity: 0, x: '-100%' }, - xl: { opacity: 0, x: '-100%' }, - }); - - const initialRight = useBreakpointValue({ - base: { opacity: 0, x: '100%' }, - md: { opacity: 0, x: '100%' }, - lg: { opacity: 0, x: '100%' }, - xl: { opacity: 0, x: '100%' }, - }); - - return ( - - - - {form.queryLocation.length > 0 && ( - <> - - - - - - )} - - - - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/select/index.ts b/src/stale/hyperglass/hyperglass/ui/components/select/index.ts deleted file mode 100644 index 242fc65..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/select/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './select'; -export { isSingleValue, isMultiValue } from './types'; -export type { SelectOnChange } from './types'; diff --git a/src/stale/hyperglass/hyperglass/ui/components/select/option.tsx b/src/stale/hyperglass/hyperglass/ui/components/select/option.tsx deleted file mode 100644 index fe9267c..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/select/option.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import { Badge, chakra, HStack } from '@chakra-ui/react'; -import { components } from 'react-select'; - -import type { OptionProps, GroupBase } from 'react-select'; -import type { SingleOption } from '~/types'; - -export const Option = ( - props: OptionProps, -): JSX.Element => { - const { label, data } = props; - const tags = Array.isArray(data.tags) ? (data.tags as string[]) : []; - return ( - > {...props}> - {label} - {tags.length > 0 && ( - - {tags.map(tag => ( - - {tag} - - ))} - - )} - - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/select/select.tsx b/src/stale/hyperglass/hyperglass/ui/components/select/select.tsx deleted file mode 100644 index 1def4e7..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/select/select.tsx +++ /dev/null @@ -1,101 +0,0 @@ -import { useDisclosure } from '@chakra-ui/react'; -import { createContext, forwardRef, useContext } from 'react'; -import ReactSelect from 'react-select'; -import { useColorMode } from '~/hooks'; -import { Option } from './option'; -import { - useContainerStyle, - useControlStyle, - useIndicatorSeparatorStyle, - useMenuListStyle, - useMenuPortal, - useMenuStyle, - useMultiValueLabelStyle, - useMultiValueRemoveStyle, - useMultiValueStyle, - useOptionStyle, - usePlaceholderStyle, - useRSTheme, - useSingleValueStyle, -} from './styles'; -import { isSingleValue } from './types'; - -import type { - MultiValue, - OnChangeValue, - Props as ReactSelectProps, - SelectInstance, -} from 'react-select'; -import type { SingleOption } from '~/types'; -import type { SelectContextProps, SelectProps } from './types'; - -const SelectContext = createContext({} as SelectContextProps); -export const useSelectContext = (): SelectContextProps => useContext(SelectContext); - -export const Select = forwardRef( - ( - props: SelectProps, - ref: React.Ref>, - ): JSX.Element => { - const { options, isMulti, onSelect, isError = false, components, ...rest } = props; - - const { isOpen, onOpen, onClose } = useDisclosure(); - - const { colorMode } = useColorMode(); - - const defaultOnChange: ReactSelectProps['onChange'] = changed => { - if (isSingleValue(changed)) { - changed = [changed] as unknown as OnChangeValue; - } - if (typeof onSelect === 'function') { - onSelect(changed as MultiValue); - } - }; - - const container = useContainerStyle({ colorMode }); - const menu = useMenuStyle({ colorMode }); - const menuList = useMenuListStyle({ colorMode }); - const control = useControlStyle({ colorMode }); - const option = useOptionStyle({ colorMode }); - const singleValue = useSingleValueStyle({ colorMode }); - const multiValue = useMultiValueStyle({ colorMode }); - const multiValueLabel = useMultiValueLabelStyle({ colorMode }); - const multiValueRemove = useMultiValueRemoveStyle({ colorMode }); - const menuPortal = useMenuPortal(); - const placeholder = usePlaceholderStyle({ colorMode }); - const indicatorSeparator = useIndicatorSeparatorStyle({ colorMode }); - const rsTheme = useRSTheme(); - - return ( - - - onChange={defaultOnChange} - onMenuClose={onClose} - onMenuOpen={onOpen} - isClearable={true} - options={options} - isMulti={isMulti} - theme={rsTheme} - components={{ Option, ...components }} - menuPortalTarget={typeof document !== 'undefined' ? document.body : undefined} - ref={ref} - styles={{ - container, - menu, - option, - control, - menuList, - menuPortal, - multiValue, - singleValue, - placeholder, - multiValueLabel, - multiValueRemove, - indicatorSeparator, - }} - {...rest} - /> - - ); - }, -); diff --git a/src/stale/hyperglass/hyperglass/ui/components/select/styles.ts b/src/stale/hyperglass/hyperglass/ui/components/select/styles.ts deleted file mode 100644 index e1e20b2..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/select/styles.ts +++ /dev/null @@ -1,245 +0,0 @@ -import { useToken } from '@chakra-ui/react'; -import { mergeWith } from '@chakra-ui/utils'; -/* eslint-disable react-hooks/exhaustive-deps */ -import { useCallback } from 'react'; -import { - useColorToken, - useColorValue, - useMobile, - useOpposingColor, - useOpposingColorCallback, -} from '~/hooks'; -import { useSelectContext } from './select'; - -import * as ReactSelect from 'react-select'; -import type { SingleOption } from '~/types'; -import type { RSStyleCallbackProps, RSStyleFunction, RSThemeFunction } from './types'; - -export const useContainerStyle = ( - props: RSStyleCallbackProps, -): RSStyleFunction<'container', Opt, IsMulti> => { - return useCallback((base, state) => { - return { width: '100%' }; - }, []); -}; - -export const useControlStyle = ( - props: RSStyleCallbackProps, -): RSStyleFunction<'control', Opt, IsMulti> => { - const { colorMode } = props; - - const { isError } = useSelectContext(); - - const minHeight = useToken('space', 12); - const borderRadius = useToken('radii', 'md'); - const color = useColorToken('colors', 'black', 'whiteAlpha.800'); - const focusBorder = useColorToken('colors', 'blue.500', 'blue.300'); - const invalidBorder = useColorToken('colors', 'red.500', 'red.300'); - // const borderColor = useColorToken('colors', 'gray.200', 'whiteAlpha.300'); - const borderColor = useColorToken('colors', 'gray.100', 'whiteAlpha.50'); - const borderHover = useColorToken('colors', 'gray.300', 'whiteAlpha.400'); - const backgroundColor = useColorToken('colors', 'white', 'blackSolid.800'); - - return useCallback( - (base, state) => { - const { isFocused } = state; - const styles = { - backgroundColor, - borderRadius, - color, - minHeight, - transition: 'all 0.2s', - borderColor: isError ? invalidBorder : isFocused ? focusBorder : borderColor, - boxShadow: isError - ? `0 0 0 1px ${invalidBorder}` - : isFocused - ? `0 0 0 1px ${focusBorder}` - : undefined, - '&:hover': { borderColor: isFocused ? focusBorder : borderHover }, - '&:hover > div > span': { backgroundColor: borderHover }, - '&:focus': { borderColor: isError ? invalidBorder : focusBorder }, - '&.invalid': { borderColor: invalidBorder, boxShadow: `0 0 0 1px ${invalidBorder}` }, - }; - return mergeWith({}, base, styles); - }, - [colorMode, isError], - ); -}; - -export const useMenuStyle = ( - props: RSStyleCallbackProps, -): RSStyleFunction<'menu', Opt, IsMulti> => { - const { colorMode } = props; - - const { isOpen } = useSelectContext(); - - const backgroundColor = useColorToken('colors', 'white', 'blackSolid.700'); - const styles = { backgroundColor, zIndex: 1500 }; - - return useCallback(base => mergeWith({}, base, styles), [colorMode, isOpen]); -}; - -export const useMenuListStyle = ( - props: RSStyleCallbackProps, -): RSStyleFunction<'menuList', Opt, IsMulti> => { - const { colorMode } = props; - - const { isOpen } = useSelectContext(); - - const borderRadius = useToken('radii', 'md'); - const backgroundColor = useColorToken('colors', 'white', 'blackSolid.700'); - const scrollbarTrack = useColorToken('colors', 'blackAlpha.50', 'whiteAlpha.50'); - const scrollbarThumb = useColorToken('colors', 'blackAlpha.300', 'whiteAlpha.300'); - const scrollbarThumbHover = useColorToken('colors', 'blackAlpha.400', 'whiteAlpha.400'); - const styles = { - borderRadius, - backgroundColor, - '&::-webkit-scrollbar': { width: '5px' }, - '&::-webkit-scrollbar-track': { backgroundColor: scrollbarTrack }, - '&::-webkit-scrollbar-thumb': { backgroundColor: scrollbarThumb }, - '&::-webkit-scrollbar-thumb:hover': { backgroundColor: scrollbarThumbHover }, - '-ms-overflow-style': { display: 'none' }, - }; - - return useCallback(base => mergeWith({}, base, styles), [colorMode, isOpen]); -}; - -export const useOptionStyle = ( - props: RSStyleCallbackProps, -): RSStyleFunction<'option', Opt, IsMulti> => { - const { colorMode } = props; - - const { isOpen } = useSelectContext(); - - const fontSize = useToken('fontSizes', 'lg'); - const disabled = useToken('colors', 'whiteAlpha.400'); - const active = useColorToken('colors', 'primary.600', 'primary.400'); - const focused = useColorToken('colors', 'primary.500', 'primary.300'); - const selected = useColorToken('colors', 'blackAlpha.400', 'whiteAlpha.400'); - - const activeColor = useOpposingColor(active); - const getColor = useOpposingColorCallback(); - - return useCallback( - (base, state) => { - const { isFocused, isSelected, isDisabled } = state; - - let backgroundColor = 'transparent'; - switch (true) { - case isDisabled: - backgroundColor = disabled; - break; - case isSelected: - backgroundColor = selected; - break; - case isFocused: - backgroundColor = focused; - break; - } - const color = getColor(backgroundColor); - - const styles = { - color: backgroundColor === 'transparent' ? 'currentColor' : color, - '&:active': { backgroundColor: active, color: activeColor }, - '&:focus': { backgroundColor: active, color: activeColor }, - backgroundColor, - fontSize, - }; - - return mergeWith({}, base, styles); - }, - [isOpen, colorMode], - ); -}; - -export const useIndicatorSeparatorStyle = ( - props: RSStyleCallbackProps, -): RSStyleFunction<'indicatorSeparator', Opt, IsMulti> => { - const { colorMode } = props; - const backgroundColor = useColorToken('colors', 'gray.200', 'whiteAlpha.300'); - const styles = { backgroundColor }; - - return useCallback(base => mergeWith({}, base, styles), [colorMode]); -}; - -export const usePlaceholderStyle = ( - props: RSStyleCallbackProps, -): RSStyleFunction<'placeholder', Opt, IsMulti> => { - const { colorMode } = props; - - const color = useColorToken('colors', 'gray.600', 'whiteAlpha.700'); - const fontSize = useToken('fontSizes', 'lg'); - - return useCallback(base => mergeWith({}, base, { color, fontSize }), [colorMode]); -}; - -export const useSingleValueStyle = ( - props: RSStyleCallbackProps, -): RSStyleFunction<'singleValue', Opt, IsMulti> => { - const { colorMode } = props; - - const color = useColorValue('black', 'whiteAlpha.800'); - const fontSize = useToken('fontSizes', 'lg'); - const styles = { color, fontSize }; - - return useCallback(base => mergeWith({}, base, styles), [color, colorMode]); -}; - -export const useMultiValueStyle = ( - props: RSStyleCallbackProps, -): RSStyleFunction<'multiValue', Opt, IsMulti> => { - const { colorMode } = props; - - const backgroundColor = useColorToken('colors', 'primary.500', 'primary.300'); - const color = useOpposingColor(backgroundColor); - const borderRadius = useToken('radii', 'md'); - const styles = { backgroundColor, color, borderRadius }; - - return useCallback(base => mergeWith({}, base, styles), [backgroundColor, colorMode]); -}; - -export const useMultiValueLabelStyle = ( - props: RSStyleCallbackProps, -): RSStyleFunction<'multiValueLabel', Opt, IsMulti> => { - const { colorMode } = props; - - const backgroundColor = useColorToken('colors', 'primary.500', 'primary.300'); - const color = useOpposingColor(backgroundColor); - const styles = { color }; - - return useCallback(base => mergeWith({}, base, styles), [colorMode]); -}; - -export const useMultiValueRemoveStyle = ( - props: RSStyleCallbackProps, -): RSStyleFunction<'multiValueRemove', Opt, IsMulti> => { - const { colorMode } = props; - - const backgroundColor = useColorToken('colors', 'primary.500', 'primary.300'); - const color = useOpposingColor(backgroundColor); - const styles = { - color, - '&:hover': { backgroundColor: 'transparent', color, opacity: 0.8 }, - }; - - return useCallback(base => mergeWith({}, base, styles), [colorMode]); -}; - -export const useRSTheme = (): RSThemeFunction => { - const borderRadius = useToken('radii', 'md') as unknown as number; - - return useCallback((t: ReactSelect.Theme): ReactSelect.Theme => ({ ...t, borderRadius }), []); -}; - -export const useMenuPortal = (): RSStyleFunction< - 'menuPortal', - Opt, - IsMulti -> => { - const isMobile = useMobile(); - const styles = { - zIndex: 1500, - }; - - return useCallback(base => mergeWith({}, base, styles), [isMobile]); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/select/types.ts b/src/stale/hyperglass/hyperglass/ui/components/select/types.ts deleted file mode 100644 index 1889776..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/select/types.ts +++ /dev/null @@ -1,58 +0,0 @@ -import * as ReactSelect from 'react-select'; - -import type { CSSObjectWithLabel } from 'react-select'; -import type { StylesProps } from 'react-select/dist/declarations/src/styles'; -import type { Theme, SingleOption } from '~/types'; - -type StylesConfigFunction = (base: CSSObjectWithLabel, props: Props) => CSSObjectWithLabel; - -export type SelectOnChange< - Opt extends SingleOption = SingleOption, - IsMulti extends boolean = boolean, -> = NonNullable, 'onChange'>>; - -export interface SelectProps - extends ReactSelect.Props { - name: string; - isMulti?: IsMulti; - isError?: boolean; - required?: boolean; - onSelect?: (s: ReactSelect.MultiValue) => void; - colorScheme?: Theme.ColorNames; -} - -export interface SelectContextProps { - colorMode: 'light' | 'dark'; - isOpen: boolean; - isError: boolean; -} - -export interface RSStyleCallbackProps { - colorMode: 'light' | 'dark'; -} - -type StyleConfigKeys = keyof ReactSelect.StylesConfig< - SingleOption, - boolean, - ReactSelect.GroupBase ->; - -export type RSStyleFunction< - K extends StyleConfigKeys, - Opt extends SingleOption, - IsMulti extends boolean, -> = StylesConfigFunction>[K]>; - -export type RSThemeFunction = (theme: ReactSelect.Theme) => ReactSelect.Theme; - -export function isSingleValue( - value: ReactSelect.SingleValue | ReactSelect.MultiValue, -): value is NonNullable> { - return value !== null && !Array.isArray(value); -} - -export function isMultiValue( - value: ReactSelect.SingleValue | ReactSelect.MultiValue, -): value is NonNullable> { - return value !== null && Array.isArray(value); -} diff --git a/src/stale/hyperglass/hyperglass/ui/components/submit-button.tsx b/src/stale/hyperglass/hyperglass/ui/components/submit-button.tsx deleted file mode 100644 index ef4cbd5..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/submit-button.tsx +++ /dev/null @@ -1,137 +0,0 @@ -import { - IconButton, - Modal, - ModalBody, - ModalCloseButton, - ModalContent, - ModalOverlay, - Popover, - PopoverArrow, - PopoverBody, - PopoverCloseButton, - PopoverContent, - PopoverTrigger, -} from '@chakra-ui/react'; -import { forwardRef } from 'react'; -import { useFormContext } from 'react-hook-form'; -import { Else, If, Then } from 'react-if'; -import { ResolvedTarget } from '~/components'; -import { DynamicIcon } from '~/elements'; -import { useColorValue, useFormState, useMobile } from '~/hooks'; - -import type { IconButtonProps } from '@chakra-ui/react'; - -type SubmitButtonProps = Omit; - -interface ResponsiveSubmitButtonProps { - isOpen: boolean; - onClose(): void; - children: React.ReactNode; -} - -const _SubmitIcon: React.ForwardRefRenderFunction< - HTMLButtonElement, - Omit -> = (props: Omit, ref) => { - const { isLoading, ...rest } = props; - return ( - } - title="Submit Query" - colorScheme="primary" - isLoading={isLoading} - aria-label="Submit Query" - {...rest} - /> - ); -}; -const SubmitIcon = forwardRef>(_SubmitIcon); - -/** - * Mobile Submit Button - */ -const MSubmitButton = (props: ResponsiveSubmitButtonProps): JSX.Element => { - const { children, isOpen, onClose } = props; - const bg = useColorValue('white', 'gray.900'); - return ( - <> - {children} - - - - - - {isOpen && } - - - - - ); -}; - -/** - * Desktop Submit Button - */ -const DSubmitButton = (props: ResponsiveSubmitButtonProps): JSX.Element => { - const { children, isOpen, onClose } = props; - const bg = useColorValue('white', 'gray.900'); - return ( - - {children} - - - - {isOpen && } - - - ); -}; - -export const SubmitButton = (props: SubmitButtonProps): JSX.Element => { - const isMobile = useMobile(); - const loading = useFormState(s => s.loading); - const { - resolvedIsOpen, - resolvedClose, - reset: resetForm, - } = useFormState(({ resolvedIsOpen, resolvedClose, reset }) => ({ - resolvedIsOpen, - resolvedClose, - reset, - })); - - const { reset } = useFormContext(); - - async function handleClose() { - reset(); - resetForm(); - resolvedClose(); - } - - return ( - - - - - - - - - - - - - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/table/body.tsx b/src/stale/hyperglass/hyperglass/ui/components/table/body.tsx deleted file mode 100644 index 0f77a7d..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/table/body.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { chakra } from '@chakra-ui/react'; - -import type { BoxProps } from '@chakra-ui/react'; - -export const TableBody = (props: BoxProps): JSX.Element => ( - -); diff --git a/src/stale/hyperglass/hyperglass/ui/components/table/button.tsx b/src/stale/hyperglass/hyperglass/ui/components/table/button.tsx deleted file mode 100644 index 6759abe..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/table/button.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import { IconButton } from '@chakra-ui/react'; - -import type { IconButtonProps } from '@chakra-ui/react'; - -type TTableIconButton = Omit; - -export const TableIconButton = (props: TTableIconButton): JSX.Element => ( - -); diff --git a/src/stale/hyperglass/hyperglass/ui/components/table/cell.tsx b/src/stale/hyperglass/hyperglass/ui/components/table/cell.tsx deleted file mode 100644 index 228576f..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/table/cell.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { chakra } from '@chakra-ui/react'; -import { useColorValue } from '~/hooks'; - -import type { BoxProps } from '@chakra-ui/react'; - -interface TableCellProps extends Omit { - bordersVertical?: [boolean, number]; - align?: 'left' | 'right' | 'center'; -} - -export const TableCell = (props: TableCellProps): JSX.Element => { - const { bordersVertical = [false, 0], align, ...rest } = props; - const [doVerticalBorders, index] = bordersVertical; - const borderLeftColor = useColorValue('blackAlpha.100', 'whiteAlpha.100'); - - let borderProps = {}; - if (doVerticalBorders && index !== 0) { - borderProps = { borderLeft: '1px solid', borderLeftColor }; - } - - return ( - - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/table/head.tsx b/src/stale/hyperglass/hyperglass/ui/components/table/head.tsx deleted file mode 100644 index 3e82fad..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/table/head.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import { chakra } from '@chakra-ui/react'; -import { useColorValue } from '~/hooks'; - -import type { BoxProps } from '@chakra-ui/react'; - -export const TableHead = (props: BoxProps): JSX.Element => { - const bg = useColorValue('blackAlpha.100', 'whiteAlpha.100'); - return ; -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/table/index.ts b/src/stale/hyperglass/hyperglass/ui/components/table/index.ts deleted file mode 100644 index aad1ca8..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/table/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './main'; diff --git a/src/stale/hyperglass/hyperglass/ui/components/table/main.tsx b/src/stale/hyperglass/hyperglass/ui/components/table/main.tsx deleted file mode 100644 index fd1eeef..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/table/main.tsx +++ /dev/null @@ -1,203 +0,0 @@ -// This rule isn't needed because react-table does this for us, for better or worse. -/* eslint react/jsx-key: 0 */ -import { Flex, Text } from '@chakra-ui/react'; -import { usePagination, useSortBy, useTable } from 'react-table'; -import { If, Then, Else } from 'react-if'; -import { CardBody, CardFooter, CardHeader, DynamicIcon } from '~/elements'; -import { useMobile } from '~/hooks'; -import { TableMain } from './table'; -import { TableCell } from './cell'; -import { TableHead } from './head'; -import { TableRow } from './row'; -import { TableBody } from './body'; -import { TableIconButton } from './button'; -import { PageSelect } from './page-select'; - -import type { TableOptions, PluginHook } from 'react-table'; -import type { Theme, TableColumn, CellRenderProps } from '~/types'; - -interface TableProps { - data: Route[]; - striped?: boolean; - columns: TableColumn[]; - heading?: React.ReactNode; - bordersVertical?: boolean; - bordersHorizontal?: boolean; - Cell?: React.FC; - rowHighlightProp?: keyof Route; - rowHighlightBg?: Theme.ColorNames; -} - -export const Table = (props: TableProps): JSX.Element => { - const { - data, - columns, - heading, - Cell, - rowHighlightBg, - striped = false, - rowHighlightProp, - bordersVertical = false, - bordersHorizontal = false, - } = props; - - const isMobile = useMobile(); - - const defaultColumn = { - minWidth: 100, - width: 150, - maxWidth: 300, - }; - - const hiddenColumns = [] as string[]; - - for (const col of columns) { - if (col.hidden) { - hiddenColumns.push(col.accessor); - } - } - - const options = { - columns, - defaultColumn, - data, - initialState: { hiddenColumns }, - } as TableOptions; - - const plugins = [useSortBy, usePagination] as PluginHook[]; - - const instance = useTable(options, ...plugins); - - const { - page, - gotoPage, - nextPage, - pageCount, - prepareRow, - canNextPage, - pageOptions, - setPageSize, - headerGroups, - previousPage, - getTableProps, - canPreviousPage, - state: { pageIndex, pageSize }, - } = instance; - - return ( - - {heading && {heading}} - - - {headerGroups.map((headerGroup, i) => ( - - {headerGroup.headers.map(column => ( - - - {column.render('Header') as React.ReactNode} - - - - - - - - - - - - - {''} - - - ))} - - ))} - - - {page.map((row, key) => { - prepareRow(row); - return ( - - {row.cells.map((cell, i) => { - const { column, row, value } = cell as CellRenderProps; - return ( - - {typeof Cell !== 'undefined' ? ( - - ) : ( - (cell.render('Cell') as React.ReactNode) - )} - - ); - })} - - ); - })} - - - - - gotoPage(0)} - isDisabled={!canPreviousPage} - icon={} - /> - previousPage()} - isDisabled={!canPreviousPage} - icon={} - /> - - - - Page{' '} - - {pageIndex + 1} of {pageOptions.length} - {' '} - - {!isMobile && ( - { - setPageSize(Number(e.target.value)); - }} - /> - )} - - - } - /> - } - onClick={() => gotoPage(pageCount ? pageCount - 1 : 1)} - /> - - - - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/table/page-select.tsx b/src/stale/hyperglass/hyperglass/ui/components/table/page-select.tsx deleted file mode 100644 index 1605ef4..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/table/page-select.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { Select } from '@chakra-ui/react'; - -import type { SelectProps } from '@chakra-ui/react'; - -export const PageSelect = (props: SelectProps): JSX.Element => { - const { value, ...rest } = props; - return ( - - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/table/row.tsx b/src/stale/hyperglass/hyperglass/ui/components/table/row.tsx deleted file mode 100644 index a0497d7..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/table/row.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import { chakra } from '@chakra-ui/react'; -import { useColorValue, useOpposingColor } from '~/hooks'; - -import type { BoxProps } from '@chakra-ui/react'; -import type { Theme } from '~/types'; - -interface TableRowProps extends BoxProps { - highlightBg?: Theme.ColorNames; - doHorizontalBorders?: boolean; - highlight?: boolean; - doStripe?: boolean; - index: number; -} - -export const TableRow = (props: TableRowProps): JSX.Element => { - const { - index = 0, - doStripe = false, - highlight = false, - highlightBg = 'primary', - doHorizontalBorders = false, - ...rest - } = props; - - const alpha = useColorValue('100', '200'); - const alphaHover = useColorValue('200', '100'); - const bgStripe = useColorValue('blackAlpha.50', 'whiteAlpha.50'); - let hoverBg = useColorValue('blackAlpha.50', 'whiteAlpha.50'); - const rowBorder = useColorValue( - { borderTop: '1px', borderTopColor: 'blackAlpha.100' }, - { borderTop: '1px', borderTopColor: 'whiteAlpha.100' }, - ); - let bg = undefined; - - if (highlight) { - bg = `${String(highlightBg)}.${alpha}`; - hoverBg = `${String(highlightBg)}.${alphaHover}`; - } else if (doStripe && index % 2 !== 0) { - bg = bgStripe; - } - const defaultBg = useColorValue('white', 'black'); - const color = useOpposingColor(bg ?? defaultBg); - const borderProps = doHorizontalBorders && index !== 0 ? rowBorder : {}; - - return ( - td': { color } }} - fontWeight={highlight ? 'bold' : undefined} - _hover={{ - cursor: 'pointer', - backgroundColor: highlight ? `${String(highlightBg)}.${alphaHover}` : hoverBg, - }} - {...borderProps} - {...rest} - /> - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/table/table.tsx b/src/stale/hyperglass/hyperglass/ui/components/table/table.tsx deleted file mode 100644 index c0fba35..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/table/table.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { chakra } from '@chakra-ui/react'; -import { useColorValue } from '~/hooks'; - -import type { BoxProps } from '@chakra-ui/react'; - -export const TableMain = (props: BoxProps): JSX.Element => { - const scrollbar = useColorValue('blackAlpha.300', 'whiteAlpha.300'); - const scrollbarHover = useColorValue('blackAlpha.400', 'whiteAlpha.400'); - const scrollbarBg = useColorValue('blackAlpha.50', 'whiteAlpha.50'); - return ( - - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/components/user-ip.tsx b/src/stale/hyperglass/hyperglass/ui/components/user-ip.tsx deleted file mode 100644 index 7a31630..0000000 --- a/src/stale/hyperglass/hyperglass/ui/components/user-ip.tsx +++ /dev/null @@ -1,100 +0,0 @@ -import { useMemo } from 'react'; -import { Button, Stack, Text, VStack, useDisclosure } from '@chakra-ui/react'; -import { Prompt } from '~/components'; -import { useConfig } from '~/context'; -import { DynamicIcon } from '~/elements'; -import { useStrf, useWtf, useColorValue } from '~/hooks'; - -interface UserIPProps { - setTarget(target: string): void; -} - -export const UserIP = (props: UserIPProps): JSX.Element => { - const { setTarget } = props; - const { onOpen, ...disclosure } = useDisclosure(); - const strF = useStrf(); - const { web } = useConfig(); - - const errorColor = useColorValue('red.500', 'red.300'); - - const noIPv4 = strF(web.text.noIp, { protocol: 'IPv4' }); - const noIPv6 = strF(web.text.noIp, { protocol: 'IPv6' }); - - const [ipv4, ipv6, query] = useWtf(); - - const hasResult = useMemo( - () => (!ipv4.isError || !ipv6.isError) && (ipv4.data?.ip !== null || ipv6.data?.ip !== null), - [ipv4, ipv6], - ); - - const show4 = useMemo(() => !ipv4.isError && ipv4.data?.ip !== null, [ipv4]); - const show6 = useMemo(() => !ipv6.isError && ipv6.data?.ip !== null, [ipv6]); - - function handleOpen(): void { - onOpen(); - query(); - } - - return ( - - {web.text.ipButton} - - } - onOpen={handleOpen} - {...disclosure} - > - - {hasResult && ( - - {web.text.ipSelect} - - )} - - {show4 && ( - - )} - {show6 && ( - - )} - {!hasResult && ( - - {web.text.ipError} - - )} - - - - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/context/hyperglass-provider.tsx b/src/stale/hyperglass/hyperglass/ui/context/hyperglass-provider.tsx deleted file mode 100644 index eca4625..0000000 --- a/src/stale/hyperglass/hyperglass/ui/context/hyperglass-provider.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { ChakraProvider, localStorageManager } from '@chakra-ui/react'; -import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; -import { createContext, useContext, useMemo } from 'react'; -import { makeTheme } from '~/util'; - -import type { Config } from '~/types'; - -interface HyperglassProviderProps { - config: Config; - children: React.ReactNode; -} - -export const HyperglassContext = createContext({} as Config); - -export const queryClient = new QueryClient(); - -export const HyperglassProvider = (props: HyperglassProviderProps): JSX.Element => { - const { config, children } = props; - const value = useMemo(() => config, []); // eslint-disable-line react-hooks/exhaustive-deps - const theme = useMemo(() => makeTheme(value.web.theme, value.web.theme.defaultColorMode), []); // eslint-disable-line react-hooks/exhaustive-deps - - return ( - - - {children} - - - ); -}; - -/** - * Get the current configuration. - */ -export const useConfig = (): Config => useContext(HyperglassContext); diff --git a/src/stale/hyperglass/hyperglass/ui/context/index.ts b/src/stale/hyperglass/hyperglass/ui/context/index.ts deleted file mode 100644 index 42f6a79..0000000 --- a/src/stale/hyperglass/hyperglass/ui/context/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './hyperglass-provider'; diff --git a/src/stale/hyperglass/hyperglass/ui/elements/animated.ts b/src/stale/hyperglass/hyperglass/ui/elements/animated.ts deleted file mode 100644 index eec5d51..0000000 --- a/src/stale/hyperglass/hyperglass/ui/elements/animated.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { chakra } from '@chakra-ui/react'; -import { motion } from 'framer-motion'; - -import type { BoxProps } from '@chakra-ui/react'; -import type { CustomDomComponent, Transition, MotionProps } from 'framer-motion'; - -type MCComponent = Parameters[0]; -type MCOptions = Parameters[1]; -type MakeMotionProps

= React.PropsWithChildren< - Omit & Omit & { transition?: Transition } ->; - -/** - * Combine `chakra` and `motion` factories. - * - * @param component Component or string - * @param options `chakra` options - * @returns Chakra component with motion props. - */ -export function motionChakra

( - component: MCComponent, - options?: MCOptions, -): CustomDomComponent> { - // @ts-expect-error I don't know how to fix this. - return motion

(chakra(component, options)); -} - -export const AnimatedDiv = motionChakra('div'); diff --git a/src/stale/hyperglass/hyperglass/ui/elements/card/body.tsx b/src/stale/hyperglass/hyperglass/ui/elements/card/body.tsx deleted file mode 100644 index 9d879bc..0000000 --- a/src/stale/hyperglass/hyperglass/ui/elements/card/body.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { Flex } from '@chakra-ui/react'; -import { useColorValue } from '~/hooks'; - -import type { FlexProps } from '@chakra-ui/react'; - -interface CardBodyProps extends Omit { - onClick?: () => boolean; -} - -export const CardBody = (props: CardBodyProps): JSX.Element => { - const { onClick, ...rest } = props; - const bg = useColorValue('white', 'dark.500'); - const color = useColorValue('dark.500', 'white'); - return ( - - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/elements/card/footer.tsx b/src/stale/hyperglass/hyperglass/ui/elements/card/footer.tsx deleted file mode 100644 index 274828e..0000000 --- a/src/stale/hyperglass/hyperglass/ui/elements/card/footer.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { Flex } from '@chakra-ui/react'; - -import type { FlexProps } from '@chakra-ui/react'; - -export const CardFooter = (props: FlexProps): JSX.Element => ( - -); diff --git a/src/stale/hyperglass/hyperglass/ui/elements/card/header.tsx b/src/stale/hyperglass/hyperglass/ui/elements/card/header.tsx deleted file mode 100644 index fa4a447..0000000 --- a/src/stale/hyperglass/hyperglass/ui/elements/card/header.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { Flex, Text } from '@chakra-ui/react'; -import { useColorValue } from '~/hooks'; - -import type { FlexProps } from '@chakra-ui/react'; - -export const CardHeader = (props: FlexProps): JSX.Element => { - const { children, ...rest } = props; - const bg = useColorValue('blackAlpha.50', 'whiteAlpha.100'); - return ( - - {children} - - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/elements/card/index.ts b/src/stale/hyperglass/hyperglass/ui/elements/card/index.ts deleted file mode 100644 index 9f66b54..0000000 --- a/src/stale/hyperglass/hyperglass/ui/elements/card/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './body'; -export * from './footer'; -export * from './header'; diff --git a/src/stale/hyperglass/hyperglass/ui/elements/code-block.tsx b/src/stale/hyperglass/hyperglass/ui/elements/code-block.tsx deleted file mode 100644 index eeb25e8..0000000 --- a/src/stale/hyperglass/hyperglass/ui/elements/code-block.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { Box } from '@chakra-ui/react'; -import { useColorValue } from '~/hooks'; - -import type { BoxProps } from '@chakra-ui/react'; - -export const CodeBlock = (props: BoxProps): JSX.Element => { - const bg = useColorValue('blackAlpha.100', 'gray.800'); - const color = useColorValue('black', 'white'); - return ( - - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/elements/countdown.tsx b/src/stale/hyperglass/hyperglass/ui/elements/countdown.tsx deleted file mode 100644 index 40a3110..0000000 --- a/src/stale/hyperglass/hyperglass/ui/elements/countdown.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import { chakra, Text } from '@chakra-ui/react'; -import ReactCountdown, { zeroPad } from 'react-countdown'; -import { If, Then, Else } from 'react-if'; -import { useColorValue } from '~/hooks'; - -import type { CountdownRenderProps } from 'react-countdown'; - -interface RendererProps extends CountdownRenderProps { - text: string; -} - -interface CountdownProps { - timeout: number; - text: string; -} - -const Renderer = (props: RendererProps): JSX.Element => { - const { hours, minutes, seconds, completed, text } = props; - const time = [zeroPad(seconds)]; - minutes !== 0 && time.unshift(zeroPad(minutes)); - hours !== 0 && time.unshift(zeroPad(hours)); - const bg = useColorValue('black', 'white'); - return ( - - - - - - - {text} - - {time.join(':')} - - - - - ); -}; - -export const Countdown = (props: CountdownProps): JSX.Element => { - const { timeout, text } = props; - const then = timeout * 1000; - return ( - } - /> - ); -}; diff --git a/src/stale/hyperglass/hyperglass/ui/elements/custom.tsx b/src/stale/hyperglass/hyperglass/ui/elements/custom.tsx deleted file mode 100644 index 928d375..0000000 --- a/src/stale/hyperglass/hyperglass/ui/elements/custom.tsx +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Render a generic script tag in the `` that contains any custom-defined Javascript, if - * defined. It no custom JS is defined, an empty fragment is rendered, which will not appear in - * the DOM. - */ -export const CustomJavascript = (props: React.PropsWithChildren): JSX.Element => { - const { children } = props; - if (typeof children === 'string' && children !== '') { - // biome-ignore lint/security/noDangerouslySetInnerHtml: required for injecting custom JS - return + + diff --git a/tests/fuzz/README.md b/tests/fuzz/README.md new file mode 100644 index 0000000..ffed9c3 --- /dev/null +++ b/tests/fuzz/README.md @@ -0,0 +1,15 @@ +# Fuzzing for aerie + +This directory contains fuzzing configurations and targets for aerie components. + +## Strategy + +We use automated fuzzing to ensure that our network protocol parsers and core logic handle unexpected or malicious input gracefully. + +## Running Fuzzers + +Fuzzing is integrated into our quality assurance process. To run tests with fuzzing-like coverage: + +```bash +just test +```