From e30efbbada65d07b613684481c082e44f9b7e7c5 Mon Sep 17 00:00:00 2001 From: Aaron Lippold Date: Thu, 5 Dec 2024 21:05:36 -0600 Subject: [PATCH 01/27] profile dev updates Signed-off-by: Aaron Lippold --- src/courses/profile-dev-test/02.md | 42 ++++++++--- src/courses/profile-dev-test/03.md | 96 +++++++++++++++++--------- src/courses/profile-dev-test/04.md | 80 ++++++++++++++++++--- src/courses/profile-dev-test/05.md | 84 ++++++++++++++++++---- src/courses/profile-dev-test/06.md | 64 +++++++++++------ src/courses/profile-dev-test/07.md | 78 +++++++++++++++++---- src/courses/profile-dev-test/08.md | 44 +++++++++--- src/courses/profile-dev-test/09.md | 52 ++++++++++---- src/courses/profile-dev-test/README.md | 69 ++++++++++++++++-- 9 files changed, 484 insertions(+), 125 deletions(-) diff --git a/src/courses/profile-dev-test/02.md b/src/courses/profile-dev-test/02.md index 153136640..edc4efad7 100644 --- a/src/courses/profile-dev-test/02.md +++ b/src/courses/profile-dev-test/02.md @@ -1,27 +1,49 @@ --- order: 2 next: 03.md -title: Repository Organization +title: Understanding Repository Organization author: Aaron Lippold --- -## Repository Organization +## Learning Objectives -The repository and profile are organized into two primary branches: `main` and `TBD`. The repository has a set of `tags` representing iterative releases of the STIG from one Benchmark major version to the next. It also has a set of releases for fixes and updates to the profile between STIG Benchmark Releases. +By the end of this section, you will: -## Branches +- Understand the branch strategy for STIG profiles +- Learn about semantic versioning in the context of STIG releases +- Know how to navigate tags and releases -### `main` branch +## Repository Structure Overview -The `main` branch contains the most recent code for the profile. It may include bugs and is typically aligned with the latest patch release for the profile. This branch is primarily used for development and testing workflows for the various testing targets. For production validation, use the latest stable patch release. +The repository uses a structured branching and tagging strategy to manage STIG profile versions and updates. This organization ensures reliable tracking of changes and stable releases for production use. -### `v{x}r{xx}` branches +## Branch Strategy -The `v{x}r{xx}` branches represent the changes between releases of the benchmark. They align with the STIG releases for the Benchmark found at the DISA STIG [Document Library](https://public.cyber.mil/stigs/downloads/). +### Main Branch -## Releases +- Purpose: Active development and testing +- Contains: Latest code and patches +- Best for: Development and testing workflows +- Note: For production, use stable releases instead -Releases use Semantic Versioning (SemVer), aligning with the STIG Benchmark versioning system of Major Version and Release. The SemVer patch number is used for updates, bug fixes, and code changes between STIG Benchmark Releases for the given product. STIG Benchmarks use a Version and Release tagging pattern `v{x}r{xx}` - like V1R12 - and we mirror that pattern in our SemVer releases. +### Version Branches (`v{x}r{xx}`) + +- Purpose: Track major STIG benchmark releases +- Example: `v1r12` for Version 1, Release 12 +- Aligns with: Official DISA STIG releases +- Reference: [DISA STIG Document Library](https://public.cyber.mil/stigs/downloads/) + +## Version Control Strategy + +### Semantic Versioning (SemVer) + +Format: `MAJOR.RELEASE.PATCH` + +- MAJOR: Matches STIG version +- RELEASE: Matches STIG release +- PATCH: Profile updates between STIG releases + +Example timeline: ## Tags diff --git a/src/courses/profile-dev-test/03.md b/src/courses/profile-dev-test/03.md index d06550b8c..d1177be71 100644 --- a/src/courses/profile-dev-test/03.md +++ b/src/courses/profile-dev-test/03.md @@ -1,29 +1,49 @@ --- order: 3 next: 04.md -title: Environment Setup +title: Environment Setup Guide author: Aaron Lippold --- -## Required Software +## Prerequisites Knowledge -- RVM, or another Ruby Management Tool -- Ruby v3 or higher -- Git -- VS Code or another IDE -- Docker (if you want to test hardened and non-hardened containers) -- AWS CLI -- AWS Account +- Basic command line experience +- Familiarity with package managers +- Understanding of environment variables +- Basic Docker concepts -## Required Accounts +## Required Software Overview -1. [AWS Console Account](https://aws.amazon.com/console/ "AWS Console Account") -2. [Platform One Account](https://login.dso.mil/register "Platform One Account") (used for container testing) -3. [P1 Harbor Token](https://login.dso.mil/auth/realms/baby-yoda/protocol/openid-connect/auth?client_id=harbor&redirect_uri=https%3A%2F%2Fregistry1.dso.mil%2Fc%2Foidc%2Fcallback&response_type=code&scope=openid+profile+email+offline_access&state=WS3BsNb5JevECV4aiy3irfegFETBHfRd "DSO Harbor Login") (used for container testing) +Each tool listed below is essential for the course. We'll explain why you need each one: -## Test Suite Environment Variables +- **RVM (Ruby Version Manager)** - Manages Ruby installations +- **Ruby v3+** - Core programming language for our testing framework +- **Git** - Version control for managing code +- **VS Code/IDE** - For writing and editing code +- **Docker** - For container-based testing +- **AWS CLI** - For interacting with AWS services -1. Environment Variables used by Test Kitchen +## Required Accounts Setup + +Create accounts with these services before proceeding: + +1. **AWS Console Account** + - Purpose: Cloud infrastructure testing + - Sign up: [AWS Console](https://aws.amazon.com/console/) + +2. **Platform One (P1) Account** + - Purpose: Access to hardened containers + - Register: [Platform One Registration](https://login.dso.mil/register) + +3. **P1 Harbor Access** + - Purpose: Container registry access + - Get token: [Harbor Login](https://login.dso.mil/auth/realms/baby-yoda/protocol/openid-connect/auth?client_id=harbor) + +## Environment Configuration + +### 1. Test Kitchen Variables + +Important variables that control testing behavior: - `INSPEC_CONTROL`: Specifies which single control to run in the `bundle exec kitchen verify` phase, useful for testing and debugging a single requirement. - default: `none` @@ -34,26 +54,40 @@ author: Aaron Lippold - `HARDENED_CONTAINER_IMAGE`: Specifies the Docker container image you consider 'hardened' (used by `kitchen.container.yml`). - default: `registry1.dso.mil/ironbank/redhat/ubi/ubi8` -2. AWS Environment +### 2. AWS Environment Setup + +**Option 1: AWS Profiles (Recommended)** + +- Easier management of multiple environments +- More secure than environment variables +- Setup guide: [AWS CLI Profiles](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html) + +**Option 2: Environment Variables** + +- Traditional AWS environment variables +- Documentation: [AWS CLI Installation](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) + +## Step-by-Step Installation Guide -You can either use standard AWS Profiles to configure your environment or use the standard AWS Environment variables to run the test suite. See: [AWS CLI Installation & Configuration](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html "AWS CLI Install Guide") +1. **Ruby Setup** + - Install RVM or alternative Ruby manager + - Install Ruby 3.1+ + - Configure OpenSSL and certificates -- Use the `AWS_PROFILE` environment variable and AWS Credential Profiles to simplify testing on multiple AWS environments or segments. This will allow you to easily manage multiple sets of AWS secrets and access keys with adjustments to a single variable. (See: [AWS CLI and Profile Setup](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html "AWS CLI Profiles Setup")) +2. **AWS Configuration** + - Install AWS CLI + - Configure credentials + - Test connection -## Setting Up Your Environment +3. **Project Setup** + - Clone repository + - Configure Harbor CLI access + - Set up Docker registry access + - Install dependencies -1. Set up your Ruby Version Management system. -2. Install Ruby 3.1 or higher. -3. Configure OpenSSL, organization certificates, etc., for your environment and tooling. -4. Set up your AWS CLI. -5. Clone the repository. -6. Obtain your [Harbor CLI Secret](https://registry1.dso.mil/harbor/projects "DSO Harbor Projects Page"). -7. After logging in, click on your User Profile "About" to get the token. -8. Log in to the P1 Docker Registry. -9. Use the command `docker login -u {PI USER NAME} -p '{HARBOR CLI SECRET}' registry1.dso.mil`. -10. Run `bundle install` in your isolated Ruby environment. +## Verification Steps -## Post-Setup Checks +Run these commands to verify your setup: - Verify your newly installed Ruby environment by running `ruby --version`. - Confirm that InSpec was installed by running `bundle exec inspec --version`. @@ -61,4 +95,4 @@ You can either use standard AWS Profiles to configure your environment or use th - Verify that your `aws-cli` is correctly configured by running `aws s3 ls` (or your preferred test command for AWS CLI). - Confirm your bundle installation by running `bundle exec inspec --version`. - Verify you can pull from RepoOne by running `docker pull https://repo1.dso.mil/dsop/redhat/ubi/ubi8`. -- Celebrate 🎉️ if everything went well. \ No newline at end of file +- Celebrate 🎉️ if everything went well. diff --git a/src/courses/profile-dev-test/04.md b/src/courses/profile-dev-test/04.md index b94d011ae..e203b5e0b 100644 --- a/src/courses/profile-dev-test/04.md +++ b/src/courses/profile-dev-test/04.md @@ -5,20 +5,80 @@ title: Test your Test Environment author: Aaron Lippold --- -## Getting to know the Testing Suite +## Learning Objectives -Once you've set up the necessary tools, you're ready to run the profile. The testing environment is determined by Test Kitchen using environment variables. +- Understand the different testing environments available +- Learn how to use Test Kitchen commands +- Execute your first test run +- Troubleshoot common testing issues -There are four testing environments to choose from: +## Introduction -1. AWS VPC Testing: This environment uses an AWS VPC for testing. -2. Docker Testing: This environment uses Docker containers for testing. -3. Vagrant Testing: This environment uses Vagrant virtual machines for testing. -4. Local Testing: This environment uses your local machine for testing. +Before diving into testing your security profiles, let's understand the testing environment and tools we'll be using. This module will guide you through the Test Kitchen framework and help you run your first test. -The specifics of each environment's configuration are detailed in the following sections. +## Available Testing Environments -## Getting Your First Test Kitchen (TK) Run +You have four options for setting up your testing environment: + +📦 **Docker Testing** + +- Uses containers for lightweight, fast testing +- Perfect for local development +- Minimal resource requirements + +🌥️ **AWS VPC Testing** + +- Uses AWS infrastructure +- Ideal for production-like environments +- Requires AWS credentials + +🖥️ **Vagrant Testing** + +- Uses virtual machines locally +- Great for isolated testing +- Supports multiple OS environments + +💻 **Local Testing** + +- Uses your local machine +- Fastest to set up +- Best for initial development + +## Test Kitchen Lifecycle + +Test Kitchen follows a four-stage lifecycle: + +1. **Create** 🏗️ + - Sets up testing instance + - Prepares login credentials + - Initializes testing environment + +2. **Converge** 🔄 + - Runs configuration management + - Applies system settings + - Prepares system state + +3. **Verify** ✅ + - Executes InSpec profile + - Runs security tests + - Reports results + +4. **Destroy** 🗑️ + - Cleans up resources + - Removes test instances + - Resets environment + +## Running Your First Test + +### Prerequisites + +Before starting, ensure you have: + +- Test Kitchen installed +- Proper environment variables set +- Required credentials configured + +### Basic Commands For each of these examples, you need to update the `KITCHEN_LOCAL_YAML` environment variable to point to the correct `kitchen..yaml` file. Ensure that any required supporting environment settings, environment variables, profiles, etc., are in place. See Environment Variables and Testing Target Environments for more information. @@ -44,4 +104,4 @@ You can also isolate which of the 'target suites' - either `vanilla` or `hardene ## Useful Test Kitchen Commands - `login`: Allows you to easily log in using the credentials created when you ran `bundle exec kitchen create`. -- `test`: Runs all the Test Kitchen stages starting with create through destroy to easily allow you to go through a full clean test run. \ No newline at end of file +- `test`: Runs all the Test Kitchen stages starting with create through destroy to easily allow you to go through a full clean test run. diff --git a/src/courses/profile-dev-test/05.md b/src/courses/profile-dev-test/05.md index 0463d8cb5..ab96b28ff 100644 --- a/src/courses/profile-dev-test/05.md +++ b/src/courses/profile-dev-test/05.md @@ -6,18 +6,38 @@ author: Aaron Lippold --- ## AWS Testing Setup +> +> Note: This guide assumes basic familiarity with AWS. If you're new to AWS, please review the [AWS Getting Started Guide](https://aws.amazon.com/getting-started/) first. -1. Configure your AWS CLI and set up your AWS Credentials. -2. Test your AWS CLI access by running: `aws s3 ls`. -3. Clone the repository. -4. Navigate to the profile repository root directory. -5. Set the environment variable for the kitchen configuration file: `export KITCHEN_LOCAL_YAML=kitchen.ec2.yml`. - 1. This uses the [kitchen-ec2 driver](https://kitchen.ci/docs/drivers/aws/ "Test Kitchen AWS EC2 Driver Documentation"). -6. (Optional) Set a specific control to run: `export INSPEC_CONTROL='SV-230222'`. +1. Configure your AWS CLI and set up your AWS credentials + - If you haven't installed AWS CLI, [download it here](https://aws.amazon.com/cli/) + - Run `aws configure` to set up your credentials +2. Verify AWS CLI access: `aws s3 ls` + - If this fails, check your credentials and permissions +3. Clone the repository +4. Navigate to the root directory of the profile repository +5. Configure Kitchen for AWS EC2: + + ```bash + export KITCHEN_LOCAL_YAML=kitchen.ec2.yml + ``` + + > The kitchen-ec2 driver enables TestKitchen to create and manage AWS EC2 instances for testing + +6. (Optional) Target a specific control: + + ```bash + export INSPEC_CONTROL='SV-230222' + ``` ## Running Through the AWS Test Suite +> +> Understanding the Test Workflow: +> +> - **Vanilla**: Represents an unmodified baseline system +> - **Hardened**: Represents a system with security controls applied -6. List the kitchen instances with: `bundle exec kitchen list`. You should see something like this: +7. List the kitchen instances with: `bundle exec kitchen list`. You should see something like this: ```shell Instance Driver Provisioner Verifier Transport Last Action Last Error @@ -25,7 +45,15 @@ author: Aaron Lippold hardened-rhel-8 Ec2 AnsiblePlaybook Inspec Ssh Verified None ``` -7. Create a kitchen instance: `bundle exec kitchen create vanilla`. +### Key Testing Steps Explained + +8. **Create** the test instance: + + ```bash + bundle exec kitchen create vanilla + ``` + + > This step launches a fresh EC2 instance for testing ```shell ➜ redhat-enterprise-linux-8-stig-baseline git:(main*)bundle exec kitchen create vanilla @@ -36,7 +64,13 @@ author: Aaron Lippold -----> Test Kitchen is finished. (0m1.21s) ``` -8. Converge the kitchen instance: `bundle exec kitchen converge`. +9. **Converge** the instance: + + ```bash + bundle exec kitchen converge vanilla + ``` + + > Convergence applies the necessary configurations to prepare the system for testing ```shell ➜ redhat-enterprise-linux-8-stig-baseline git:(main*)bundle exec kitchen converge vanilla @@ -54,7 +88,7 @@ author: Aaron Lippold -----> Test Kitchen is finished. (1m13.52s) ``` -9. Run InSpec on the kitchen instance: `bundle exec kitchen verify`. +10. Run InSpec on the kitchen instance: `bundle exec kitchen verify`. ```shell ➜ redhat-enterprise-linux-8-stig-baseline git:(main*)bundle exec kitchen verify vanilla @@ -77,7 +111,27 @@ author: Aaron Lippold -----> Test Kitchen is finished. (0m6.62s) ``` -10. Destroy the kitchen instance: `bundle exec kitchen destroy vanilla`. -11. For steps that apply to making updates, patches, and updates to the profile, see the next section, [Updating the Profile](#18-updating-the-profile). -12. Your InSpec scan results are located in the `./spec/results/` directory, named `./spec/results/rhel-8_*`. -13. Use [Heimdall Lite](https://heimdall-lite.mitre.org "MITRE Heimdall Lite") to load both the `hardened` and `vanilla` results to ensure your changes and updates, "failed as expected and passed as expected and covered your courner cases." +### Analyzing Results + +- Results Location: `./spec/results/rhel-8_*` +- Use [Heimdall Lite](https://heimdall-lite.mitre.org) to compare results: + 1. Load both `hardened` and `vanilla` results + 2. Compare to verify expected failures and passes + 3. Review corner cases for complete coverage + +::: tip Always remember to pause or destroy your test instances after testing to avoid unnecessary AWS charges: +> +> ```bash +> bundle exec kitchen destroy vanilla +> ``` +> +> ```sh +> Pause your instance in the AWS Console +> ``` +> +::: + +1. Destroy the kitchen instance: `bundle exec kitchen destroy vanilla`. +2. For steps that apply to making updates, patches, and updates to the profile, see the next section, [Updating the Profile](#18-updating-the-profile). +3. Your InSpec scan results are located in the `./spec/results/` directory, named `./spec/results/rhel-8_*`. +4. Use [Heimdall Lite](https://heimdall-lite.mitre.org "MITRE Heimdall Lite") to load both the `hardened` and `vanilla` results to ensure your changes and updates, "failed as expected and passed as expected and covered your corner cases." diff --git a/src/courses/profile-dev-test/06.md b/src/courses/profile-dev-test/06.md index e5cc83928..e46d84fd6 100644 --- a/src/courses/profile-dev-test/06.md +++ b/src/courses/profile-dev-test/06.md @@ -1,25 +1,47 @@ --- order: 6 next: 07.md -title: Docker Testing Suite +title: Testing with Docker Containers author: Aaron Lippold --- -## Docker Suite Setup +## Learning Objectives -1. Make sure Docker or Podman is running -2. Login to your docker registry -3. Clone the repository -4. Go into the profile repository root dir -5. `bundle install` -6. `export KITCHEN_LOCAL_YAML=kitchen.container.yml` (uses the [kitchen-dokken driver](https://kitchen.ci/docs/drivers/dokken/ "Test Kitchen Dokken Driver Documentation")) -7. `export VANILLA_CONTAINER_IMAGE=registry.access.redhat.com/ubi8/ubi:8.9-1028` -8. `export HARDENED_CONTAINER_IMAGE=registry1.dso.mil/ironbank/redhat/ubi/ubi8` -9. (optional) `export INSPEC_CONTROL='SV-230222'` +- Understand how to set up a Docker testing environment +- Learn to use Test Kitchen with Docker containers +- Execute and interpret InSpec tests in containers +- Analyze test results using Heimdall Lite + +## Prerequisites + +- Docker or Podman installed and running +- Access to required container registries +- Basic understanding of command line operations + +## Environment Setup + +Before running tests, configure your environment: + +1. Ensure Docker/Podman is running +2. Authenticate with your container registry +3. Clone the test profile repository +4. Navigate to the profile's root directory +5. Run `bundle install` to install dependencies + +## Configure Test Kitchen + +Set these environment variables: + +```shell +> export KITCHEN_LOCAL_YAML=kitchen.container.yml +> export VANILLA_CONTAINER_IMAGE=registry.access.redhat.com/ubi8/ubi:8.9-1028 +> export HARDENED_CONTAINER_IMAGE=registry1.dso.mil/ironbank/redhat/ubi/ubi8 +> (optional) export INSPEC_CONTROL='SV-230222' +``` ## Running Through the Docker Test Suite -10. List the kitchen instances with: `bundle exec kitchen list` +1. List the kitchen instances with: `bundle exec kitchen list` ```shell ➜ redhat-enterprise-linux-8-stig-baseline git:(main*)bundle exec kitchen list @@ -28,7 +50,7 @@ vanilla-ubi8 Dokken Dummy Inspec Dokken hardened-ubi8 Dokken Dummy Inspec Dokken ``` -11. Create the kitchen instance: `bundle exec kitchen create vanilla` +2. Create the kitchen instance: `bundle exec kitchen create vanilla` ```shell -----> Starting Test Kitchen (v3.5.1) @@ -41,7 +63,7 @@ hardened-ubi8 Dokken Dummy Inspec Dokken -----> Test Kitchen is finished. (0m1.77s) ``` -12. Converge the kitchen instance: `bundle exec kitchen converge vanilla` +3. Converge the kitchen instance: `bundle exec kitchen converge vanilla` ```shell ➜ redhat-enterprise-linux-8-stig-baseline git:(main*)bundle exec kitchen converge vanilla @@ -52,7 +74,7 @@ hardened-ubi8 Dokken Dummy Inspec Dokken -----> Test Kitchen is finished. (0m0.88s) ``` -13. Run InSpec on the kitchen instance: `bundle exec kitchen verify vanilla` +4. Run InSpec on the kitchen instance: `bundle exec kitchen verify vanilla` ```shell -----> Starting Test Kitchen (v3.5.1) @@ -71,9 +93,9 @@ Profile Summary: 0 successful controls, 1 control failure, 0 controls skipped Test Summary: 0 successful, 4 failures, 0 skipped ``` -## This is not the **Error** Your Looking For, move along... +## This is not the **Error** Your Looking For, move along -The error below is just Test Kitchen telling you that not all of the Contrls in the profile passed. +The error below is just Test Kitchen telling you that not all of the `controls` of the profile passed. ```shell >>>>>> ------Exception------- @@ -85,6 +107,8 @@ The error below is just Test Kitchen telling you that not all of the Contrls in >>>>>> Also try running `kitchen diagnose --all` for configuration ``` -14. For steps that apply to making updates, patches, and updates to the profile, see the next section, [Updating the Profile](#updating-the-profile). -15. Your InSpec scan results are located in the `./spec/results/` directory, named `./spec/results/ubi-8_*.` -16. Use Heimdall Lite to load both the `hardened` and `vanilla` results to ensure your changes and updates, "failed as expected and passed as expected and covered your corner cases." +## Next Steps + +1. For steps that apply to making updates, patches, and updates to the profile, see the next section, [Updating the Profile](#updating-the-profile). +2. Your InSpec scan results are located in the `./spec/results/` directory, named `./spec/results/ubi-8_*.` +3. Use Heimdall Lite to load both the `hardened` and `vanilla` results to ensure your changes and updates, "failed as expected and passed as expected and covered your corner cases." diff --git a/src/courses/profile-dev-test/07.md b/src/courses/profile-dev-test/07.md index 3924ca960..819aee9c4 100644 --- a/src/courses/profile-dev-test/07.md +++ b/src/courses/profile-dev-test/07.md @@ -1,23 +1,35 @@ --- order: 7 next: 08.md -title: Updating - Choosing Your Approach +title: Pull Request Strategies - Choosing Your Approach author: Aaron Lippold --- -## Choosing Your Approach +## Learning Objectives -This project follows the [GitFlow model](https://docs.github.com/en/get-started/quickstart/github-flow "GitFlow Announcement Blog") for managing the repository, accepting pull requests (PRs), and merging changes into the profile. +By the end of this section, you will: -## Micro vs Massive Pull Requests (PRs) +- Understand GitFlow workflow for repository management +- Compare micro and macro PR approaches +- Learn when to use different PR strategies -In software development, the decision between making many small pull requests (micro PRs) or fewer, larger pull requests (massive PRs) often depends on the context. Both approaches have their benefits and challenges. +## GitFlow Overview -### Micro PRs +This project uses the [GitHub Flow](https://docs.github.com/en/get-started/quickstart/github-flow) model for managing changes. This workflow helps maintain code quality and collaboration through systematic pull requests (PRs). -Micro PRs involve making frequent, small changes to the codebase. Each PR is focused on a single task or feature. +## Understanding Pull Request Strategies -**Benefits:** +When contributing to a project, you'll need to choose between two main PR approaches: + +### 1. Micro PRs (Small, Frequent Changes) + +**Characteristics:** + +- Single task or feature per PR +- Usually < 200 lines of code +- Frequent submissions + +**Advantages:** - **Easier to review:** Small changes are easier for reviewers to understand and provide feedback on. - **Less risk:** If a problem arises, it's easier to identify and fix because the change is isolated. @@ -28,11 +40,15 @@ Micro PRs involve making frequent, small changes to the codebase. Each PR is foc - **Overhead:** Each PR requires its own review and merge process, which can be time-consuming. - **Context switching:** Frequent changes can disrupt the flow of work, especially if developers have to switch between different tasks. -### Macro PRs +### 2. Macro PRs (Large, Comprehensive Changes) + +**Characteristics:** -Macro PRs involve making larger, more comprehensive changes to the codebase. Each PR may encompass multiple tasks or features. +- Multiple related changes +- Larger codebase modifications +- Less frequent submissions -**Benefits:** +**Advantages:** - **Efficiency:** Larger PRs can be more efficient because they require fewer reviews and merges. - **Coherence:** By grouping related changes together, it may be easier to understand how different parts of the codebase interact. @@ -43,11 +59,47 @@ Macro PRs involve making larger, more comprehensive changes to the codebase. Eac - **Higher risk:** If a problem arises, it can be more difficult to identify and fix because it could be anywhere in the large set of changes. - **Delayed feedback:** With fewer PRs, there are fewer opportunities for feedback. -### PR Strategies for Different Update Scenarios +## Practical Guidelines + +### When to Use Micro PRs + +- Bug fixes +- Small feature additions +- Documentation updates +- Performance optimizations + +### When to Use Macro PRs + +- Major version upgrades +- Complex feature implementations +- Architectural changes +- Large-scale refactoring + +## Update Scenarios The choice between micro and massive PRs can significantly impact the workflows in our `Patch Update`, `Release Update`, and `Major Version Update`. - **Patch and Release Updates:** These updates typically involve minor changes or additions, which can be easily managed with either micro or massive PRs. The choice depends on your team's preference for review speed and context switching. + - **Major Version or Large Jump Release Updates:** These updates require a thorough review of every single control and requirement. They also necessitate extensive testing, both automated (via the CI/CD testing matrix) and manual. In this scenario, the overhead of managing multiple micro or mini PRs can be substantial. However, the benefit is that it allows for more granitary control and review of changes. It's also easier to isolate and fix issues that arise during testing. -In conclusion, the choice between micro and massive PRs depends on the specific needs and circumstances of your project. It's important to strike a balance that maximizes efficiency while minimizing risk, and fosters effective collaboration within your team. +## Practice Exercise + +Consider these scenarios and decide which PR strategy you would use: + +1. Fixing a typo in documentation +2. Implementing a new security control +3. Upgrading to a new major version + +## Summary + +- Choose micro PRs for better review quality and reduced risk +- Use macro PRs for cohesive, large-scale changes +- Consider project context and team preferences +- Balance efficiency with maintainability + +## Review Questions + +1. What are the key differences between micro and macro PRs? +2. Which PR strategy would you choose for a critical security patch? +3. How does GitFlow support different PR strategies? diff --git a/src/courses/profile-dev-test/08.md b/src/courses/profile-dev-test/08.md index 9db384a75..e26f9135a 100644 --- a/src/courses/profile-dev-test/08.md +++ b/src/courses/profile-dev-test/08.md @@ -1,22 +1,48 @@ --- order: 8 next: 09.md -title: Secruity Benchmarks vs Traditional Software +title: Security Benchmarks vs Traditional Software author: Aaron Lippold --- -## Security Benchmark Code VS Traditional Software Applications +## Understanding Security Benchmarks -When planning your team's approach, remember that a Security Benchmark is only considered 'complete and valid' when all requirements for that specific Release or Major Version are met. This differs from traditional software projects where features and capabilities can be incrementally added. +## Key Differences from Traditional Software -## Security Benchmarks Are Release-Specific +Security benchmarks differ from traditional software development in several critical ways: -A Security Benchmark and ***its corresponding InSpec Profile*** are only applicable within the context of a specific 'Release' of that Benchmark. +1. **Completeness Requirement** + - Traditional Software: Can be released with partial features + - Security Benchmarks: Must meet ALL requirements for a specific version -The choice between a `micro` or `massive` approach depends more on your team's work style preference. +2. **Version Specificity** + - Each benchmark version is a complete, standalone entity + - InSpec profiles must match their corresponding benchmark version exactly -Regardless of the approach, the final release of the Benchmark will be the same. The deciding factors for its readiness for release are the expected thresholds, hardening, and validation results. +## Development Approaches -## 'main' is `out of scope` for a Benchmark +Two common approaches to benchmark development: -Benchmarks do not accommodate 'incremental requirements'. Therefore, your team should always work off a fork of the last release. If there is a 'main' or 'development' branch in your profile, it should be considered as a candidate for merging into the next patch or update release. \ No newline at end of file +- **Micro Approach**: Gradual, incremental development +- **Massive Approach**: Complete implementation in larger chunks + +> 💡 **Key Point**: Both approaches are valid - choose based on your team's workflow preferences. + +## Version Control Best Practices + +### Working with Branches + +- ⚠️ Never work directly on 'main' +- Always fork from the latest release +- Consider 'main' or 'development' branches as pre-release candidates + +## Practical Exercise + +Try answering these questions: + +1. Why can't security benchmarks be released incrementally? +2. How should you handle new requirements that arise between releases? +3. What branch strategy would you use for a new benchmark version? + +--- +**Remember**: Security benchmark validation is binary - it either meets all requirements or it doesn't. diff --git a/src/courses/profile-dev-test/09.md b/src/courses/profile-dev-test/09.md index f875f0550..d4d4e2942 100644 --- a/src/courses/profile-dev-test/09.md +++ b/src/courses/profile-dev-test/09.md @@ -1,29 +1,55 @@ --- order: 9 next: 10.md -title: Types of Profile Updates +title: Understanding Profile Updates author: Aaron Lippold --- -## Types of Benchmark Updates +## Learning Objectives -When updating the profile, you'll be making one of three types of changes: +By the end of this section, you will be able to: -1. **Patch Update:** These frequent updates cover missing corner cases of testing for one or more benchmark requirements, or improvements to the InSpec code for a requirement. These updates result in a new patch release of the benchmark, such as going from `v1.12.4` to `v1.12.5`. We aim to release these updates on a regular schedule, either weekly, bi-weekly, or monthly. -2. **Release Update:** These updates occur when the STIG Benchmark owner releases an updated version of the STIG, for example, going from Red Hat Enterprise Linux V1R12 to V1R13. -3. **Major Version Update:** These updates occur when a software vendor releases a new major version of their product's STIG. For example, when Red Hat releases version 9 of Red Hat Enterprise Linux or Microsoft releases a new major version of Windows, such as Windows 2024 or Windows 12. +- Identify the three types of profile updates +- Understand the scope of STIG and CIS Benchmark updates +- Recognize the forward-only nature of security benchmark updates -### Scope of the Update Patterns +## Types of Profile Updates -The STIGs and CIS Benchmarks are scoped within the Major Version of the software products they represent. +Security benchmark profiles require regular updates to maintain their effectiveness. Let's explore the three main types of updates: -Updates or amendments to a Benchmark's requirements are tracked within the 'Releases' of the Benchmark. +### 1. Patch Updates (Minor Changes) -As we mentioned in the previous section, ***there is no concept of 'back-patching'***; it is a ***'forward-only'*** process. +- Frequency: Weekly to monthly +- Purpose: Address corner cases and improve testing code +- Version Change Example: v1.12.4 → v1.12.5 +- Typical Changes: Bug fixes, code improvements, test coverage expansion -Each requirement is indexed from their source SRG document, aligned to a CCI, and then given a unique `Rule ID` and `STIG ID` in the respective XCCDF Benchmark document. +### 2. Release Updates (Intermediate Changes) -Here is an example of various indices you may recognize: +- Triggered by: STIG Benchmark owner releases +- Example: RHEL STIG V1R12 → V1R13 +- Includes: New security requirements, updated controls + +### 3. Major Version Updates + +- Triggered by: New product versions +- Examples: + - RHEL 8 → RHEL 9 + - Windows Server 2019 → Windows Server 2022 + +## Understanding Update Scope + +Important concepts to remember: + +- Updates are version-specific +- Changes only move forward ("forward-only" process) +- No "back-patching" to older versions +- Each requirement maps to: + - Source SRG document + - Control Correlation Identifier (CCI) + - Unique Rule and STIG IDs + +Example requirement identifiers: ```ruby tag gtitle: 'SRG-OS-000480-GPOS-00227' @@ -32,4 +58,4 @@ tag rid: 'SV-230221r858734_rule' tag stig_id: 'RHEL-08-010000' tag fix_id: 'F-32865r567410_fix' tag cci: ['CCI-000366'] -``` \ No newline at end of file +``` diff --git a/src/courses/profile-dev-test/README.md b/src/courses/profile-dev-test/README.md index fdb024dc2..348b20072 100644 --- a/src/courses/profile-dev-test/README.md +++ b/src/courses/profile-dev-test/README.md @@ -5,22 +5,83 @@ title: Development & Testing InSpec Profile author: Aaron Lippold --- +📚 **Difficulty Level**: Intermediate +⏱️ **Estimated Time**: 2-3 hours + +## Learning Objectives + +By completing this module, you will be able to: + +- Build and validate InSpec profiles using Test Kitchen +- Configure local testing environments for security compliance +- Execute tests using Docker and AWS environments +- Implement continuous testing workflows +- Troubleshoot common profile development issues + +## Prerequisites + +Before starting this module, ensure you have: + +- Basic knowledge of Ruby ([Learn Ruby Basics](https://ruby-lang.org/en/documentation/quickstart/)) +- Docker or Podman installed ([Docker Installation Guide](https://docs.docker.com/get-docker/)) +- AWS Free Tier account (optional) ([AWS Sign Up](https://aws.amazon.com/free/)) +- Platform One account ([P1 Registration](https://login.dso.mil/)) +- Git installed ([Git Setup Guide](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)) + +## Skills Assessment + +Before proceeding, verify you can: + +- [ ] Run basic Ruby commands +- [ ] Execute Docker containers +- [ ] Use Git for version control +- [ ] Navigate command line interfaces + ## Overview -The development and testing of profiles is accomplished by a variety of tools including: Ruby, the Test Kitchen suite, InSpec compliance language, Ansible, Docker, and shell scripting (bash/zsh). To contribute with Pull Requests and fixes, you'll need to set up your local test suite following the instructions provided below. +The development and testing of profiles are accomplished using a variety of tools, including Ruby, the Test Kitchen suite, InSpec compliance language, Ansible, Docker, and shell scripting (bash/zsh). To contribute with Pull Requests and fixes, you'll need to set up your local test suite by following the instructions provided below. + +### Key Tools Explained + +- **Test Kitchen**: Integration testing framework + - Example: `kitchen test` validates your InSpec profiles + - Use case: Automated compliance testing +- **Docker/Podman**: Container platforms + - Example: `docker run` creates isolated test environments + - Use case: Consistent testing across platforms +- **InSpec**: Compliance testing framework + - Example: `inspec exec` runs compliance checks + - Use case: Security automation +- **Platform One**: DoD's DevSecOps platform + - Example: Using hardened containers + - Use case: Secure development environments + +## Development Workflow Our development and testing workflow is managed by Test Kitchen. This tool is integral to our GitHub Actions CI/CD Pipelines and is also used for local development, testing, and releasing updates, patches, and full releases of the profile. +> 💡 **Pro Tip**: When starting out, focus on Docker-based testing before moving to AWS environments. + +### Testing Environments + Test Kitchen uses Docker (or Podman, if preferred) and AWS (using free-tier resources) for testing. We provide example files for testing on a local Vagrant Red Hat (or other RHEL variant) box in the repository. +### Platform One Integration + Additionally, Test Kitchen uses the Red Hat hardened `ubi8 base container` from Platform One for testing. To test the hardened container portion of the testing suite, you'll need to set up and log in to your P1 Free account, then obtain a CLI token to pull the Platform One Iron Bank Red Hat Enterprise Linux 8 Universal Base Image (P1 IB UBI8) image into the test suite. -## Example Repository +> ⚠️ **Important**: Ensure you keep your P1 CLI token secure and never commit it to version control. + +## Getting Started with Examples This guide refers to the [MITRE RedHat Enterprise Linux 8 STIG](https://github.com/mitre/redhat-enterprise-linux-8-stig-baseline/tree/metzger_dynamic_inputs) profile, which provides a working example of the workflow described here. -Upon the release of the next patch, v1.12.1, this process and workflow will be incorporated into the `main` branch. Currently, the process is active in the 'development' branch, as linked above. +> 🔍 **Note**: Development happens in the `main` branch, with stable versions available as tagged releases. -## Checkout and Clone the Working Example +### Hands-on Practice If you would like to follow along, experiment with the workflows, and understand the process described here, feel free to fork or clone the repository above. Follow the setup and configuration steps in the next section to input your own credentials and accounts, and learn as you go! + +## Next Steps + +After setting up your environment, proceed to the next section to learn about specific testing patterns and workflows. From 5f0e7273976656b73a1e2557c3381c090f22fd0c Mon Sep 17 00:00:00 2001 From: Aaron Lippold Date: Thu, 5 Dec 2024 22:48:00 -0600 Subject: [PATCH 02/27] profile dev updates Signed-off-by: Aaron Lippold --- src/courses/profile-dev-test/10.md | 81 ++++++++++++++++++++--------- src/courses/profile-dev-test/11.md | 55 +++++++++++++++++--- src/courses/profile-dev-test/12.md | 83 +++++++++++++++++++++++++----- src/courses/profile-dev-test/13.md | 82 +++++++++++++++++++++++++---- src/courses/profile-dev-test/14.md | 71 +++++++++++++++++++++---- src/courses/profile-dev-test/15.md | 66 ++++++++++++++++++------ src/courses/profile-dev-test/16.md | 34 ++++++++++-- src/courses/profile-dev-test/17.md | 78 +++++++++++++++++++++++----- src/courses/profile-dev-test/18.md | 22 ++++++-- src/courses/profile-dev-test/19.md | 13 +++-- src/courses/profile-dev-test/20.md | 18 ++++++- src/courses/profile-dev-test/21.md | 8 +-- src/courses/profile-dev-test/22.md | 6 +-- src/courses/profile-dev-test/23.md | 6 +-- src/courses/profile-dev-test/24.md | 8 +-- src/courses/profile-dev-test/25.md | 11 +++- src/courses/profile-dev-test/26.md | 15 +++--- src/courses/profile-dev-test/27.md | 18 +++---- src/courses/profile-dev-test/28.md | 16 +++--- src/courses/profile-dev-test/29.md | 20 +++---- 20 files changed, 559 insertions(+), 152 deletions(-) diff --git a/src/courses/profile-dev-test/10.md b/src/courses/profile-dev-test/10.md index e81db23fa..a3a19a342 100644 --- a/src/courses/profile-dev-test/10.md +++ b/src/courses/profile-dev-test/10.md @@ -1,24 +1,50 @@ --- order: 10 next: 11.md -title: What Is Done for a Control? +title: What Is `Done` for a Control? author: Aaron Lippold --- +# Understanding Control Completion in Security Automation + +## Learning Objectives + +By the end of this section, you will be able to: + +- Define the criteria for a "done" security control +- Apply the MITRE SAF yardstick to evaluate controls +- Implement effective control testing strategies +- Create and maintain progress tracking systems +- Debug common control implementation issues + +## Knowledge Check Questions + +Before we begin, consider these questions: + +1. What makes a security control "complete"? +2. How do you verify a control works in different environments? +3. What's the difference between "passing well" and just passing? + +## Introduction + +Understanding when a security control is truly "done" is crucial for security automation engineers. This section will guide you through the criteria, best practices, and practical approaches to ensure your controls are complete and effective. + ## When is a Control Considered 'Done' You and your team might be wondering what 'done' means for a security control in your profile. Here are a few things to consider: -- The security automation content and its tests are essentially a refactoring of the 'validation' and 'remediation' guidance already established by the benchmark. -- The security automation content tests should fully capture the spirit - or intention - of the guidance, including its caveats, notes, discussion, and 'validation' and 'remediation' content. -- The tests can - and usually do - capture known 'corner cases and security best practices' that are sometimes indirectly or not directly addressed by the benchmark but implied by the spirit of the security requirement being addressed. -- These tests, like all human-written code, may not be perfect. They will need updates and will evolve as our knowledge of the system and benchmark grows. We use the profile in production and real-world environments. In other words, don't let the pursuit of perfection hinder progress. +1. The security automation content and its tests are essentially a refactoring of the 'validation' and 'remediation' guidance already established by the benchmark. +2. The security automation content tests should fully capture the spirit - or intention - of the guidance, including its caveats, notes, discussion, and 'validation' and 'remediation' content. +3. The tests can - and usually do - capture known 'corner cases and security best practices' that are sometimes indirectly or not directly addressed by the benchmark but implied by the spirit of the security requirement being addressed. +4. These tests, like all human-written code, may not be perfect. They will need updates and will evolve as our knowledge of the system and benchmark grows. We use the profile in production and real-world environments. In other words, don't let the pursuit of perfection hinder progress. The 'is it done' litmus test is not solely determined by a perfect InSpec control or describe and expect blocks. It also heavily relies on you, the security automation engineer. Your experience, understanding of the platform you're working on, and the processes that you and your team have collectively agreed upon are all vital components. Trust your established expected test outcomes, the guidance document, and the CI/CD testing framework. They will help you know that, to the best of your ability, you have captured the spirit of the testing required by the Benchmark. -## The MITRE Security Automation Framework 'Yardstick' +## The MITRE SAF Testing Framework + +Our framework provides a comprehensive approach to testing controls. We call this the "SAF Yardstick": We consider a control effectively tested when: @@ -37,11 +63,15 @@ We consider a control effectively tested when: 6. The test communicates effectively and clearly articulates the Not Reviewed condition for both the 'vanilla' and 'hardened' testing targets. 7. The tests have been constructed in a way that they do not produce Profile Errors when looping, using conditional logic, or when system conditions - such as missing files, directories, or services - are not in the expected locations. -## Defining 'Passes as Expected' +## Best Practices for Test Implementation -'Passing as expected' is the most straightforward concept as it directly corresponds to the test conditions. When the test asserts a condition, it validates that assertion and reports it to the end user in a clear and concise manner. +### Passing Tests (Passing Well) -We strive to ensure that when we report a 'pass', we do so in a language that is direct, simple, and easy to understand. +A well-implemented passing test should: + +- Clearly communicate success conditions +- Use simple, direct language +- Include validation of edge cases For example: @@ -54,13 +84,13 @@ For example: - The conditions for the Not Reviewed and Not Applicable states for the control, if any. -## Defining `Fails as Expected` - -'Failing as expected' is a less straightforward concept as it doesn't always directly correspond to the test conditions. When the test asserts a condition and it fails, the reason for that failure should be communicated to the end user in a clear and concise manner. +### Failing Tests (Failing Well) -However, as we all know, a test may fail for more than one reason. Sometimes, the reason for failure might be connected to human error, conditions on the system such as extra lines, files, or housekeeping on the system that was not done, etc. All these factors may need to be accounted for in your tests and perhaps captured in your output and 'reasons' for failure. +When implementing failure scenarios, ensure: -This is where the above 'best practices' come into play. You don't just test in optional 'pass' and 'fail' conditions only, but also 'dirty things up' a bit and make sure that your 'failure' cases are robust enough to handle the real world and semi-perfect conditions. +- Clear error messages +- Actionable feedback +- Proper error handling For example: @@ -77,17 +107,22 @@ For example: - Misconfigurations, extra lines in files, extra settings, missing files, etc. -## Defining `Communicates Effectively` +## Hands-on Exercise 1: Creating Your First Control + +Let's practice implementing a basic control: -Clear communication from your testing suite may require you to use a combination of approaches, but the extra time and effort is well worth it. +1. Create a basic control test +2. Add passing and failing scenarios +3. Implement clear communication +4. Test edge cases -Here are some methods you can employ and things to consider: +## Key Takeaways -- Use `expect` vs `describe` statements in cases where you have multi-part or multi-phase test cases. -- Break up your `describe` statements into multiple layers so that the final output to the end user is clear and concise. -- Post-process and format both 'passing' and 'failures' so that they are useful to the end user later and clear for communication to other team members. This could be in the form of lists or bulleted lists. -- Collect 'failing results' as simple, clear lists or bullets that are easy to 'copy and paste'. This makes it easier for teams to know 'what they have to fix and where'. -- Consider assisting 'Manual Review'/'Not Reviewed' tests by collecting needed information, such as users, groups, or other elements that you are asking the user or another person to review. While we may not be able to fully automate the test, if the 'automation can help collect' then it still adds value. +- Control completion is more than just passing tests +- Use the SAF Yardstick as your guide +- Clear communication is essential +- Track progress consistently +- Group similar controls for efficiency ## Tracking Your Progress @@ -133,4 +168,4 @@ The MITRE SAF team has found the following best practices effective for organizi 4. **Always Strive to Have a Full Test Suite:** Ensuring the fidelity of testing is crucial. This principle applies to both the 'vanilla' and 'hardened' contexts, as well as to the 'primary deployment platforms' that your profile supports. These platforms might include Virtual Machines, Cloud Instances, and Container Deployments. Your goal should be to have both 'hardened' and 'vanilla' baselines for each deployment target. This strategy allows for easy provisioning of each platform. It also facilitates easy testing of your control on each platform as you progress from one control to another. This practice ensures that you are crafting the best possible tests for each target platform and configuration. -5. **Try to Test Locally First, with the Pipeline Second:** One of the key patterns highlighted in this guidance is the combination of local and CI/CD-based testing. We advocate for both approaches for a specific reason. When you are working on multiple controls, it's more efficient to test each control on each platform locally. This method is quicker than waiting for the CI/CD pipeline to create a new deployment of the test and target platforms each time. Once you have configured your targets and platforms locally with Test Kitchen, you can be confident in their stability. You should prioritize these local targets for initial testing. After testing them and when you are ready to proceed to the next control, push those updates to the CI/CD pipeline. This step verifies that your controls still function in a clean environment. This approach promotes a more efficient workflow process and eliminates the need for continuous 'push and wait' for the pipeline. \ No newline at end of file +5. **Try to Test Locally First, with the Pipeline Second:** One of the key patterns highlighted in this guidance is the combination of local and CI/CD-based testing. We advocate for both approaches for a specific reason. When you are working on multiple controls, it's more efficient to test each control on each platform locally. This method is quicker than waiting for the CI/CD pipeline to create a new deployment of the test and target platforms each time. Once you have configured your targets and platforms locally with Test Kitchen, you can be confident in their stability. You should prioritize these local targets for initial testing. After testing them and when you are ready to proceed to the next control, push those updates to the CI/CD pipeline. This step verifies that your controls still function in a clean environment. This approach promotes a more efficient workflow process and eliminates the need for continuous 'push and wait' for the pipeline. diff --git a/src/courses/profile-dev-test/11.md b/src/courses/profile-dev-test/11.md index 5a2421289..b94741697 100644 --- a/src/courses/profile-dev-test/11.md +++ b/src/courses/profile-dev-test/11.md @@ -1,20 +1,59 @@ --- order: 11 next: 12.md -title: Rules of the Road +title: Security Benchmark Profile Management author: Aaron Lippold --- -## Best Practices for Profile Managment +## Introduction to Profile Management -When updating Benchmark Profiles, adhere to these key principles to maintain alignment with the original Guidance Documents: +Security benchmark profiles are critical tools for maintaining system security standards. Before diving into the implementation details, let's understand the fundamental principles that guide their management. -1. **Maintain Version Integrity:** **Never Merge** new requirements into older benchmark branches. This will create a 'mixed baseline' that doesn't align with any specific guidance document. Benchmarks, STIGs, and Guidance Documents form a 'proper subset' - they should be treated as 'all or nothing'. Mixing requirements from different versions can invalidate the concept of 'testing to a known benchmark'. +## Core Principles of Profile Management -2. **Benchmarks are a Complete Set of Requirements:** A Security Benchmark is 'complete and valid' only when all requirements for a specific Release or Major Version are met. Unlike traditional software projects, features and capabilities cannot be incrementally added. A Security Benchmark and its corresponding InSpec Profile are valid only within the scope of a specific 'Release' of that Benchmark. +### 1. Version Control and Integrity -3. **Release Readiness Is Predefined:** A Benchmark is considered 'ready for release' when it meets the expected thresholds, hardening, and validation results. Don't be overwhelmed by the multitude of changes across the files. Instead, focus on the specific requirement you are working on. Understand its expected failure and success states on each of the target testing platforms. This approach prevents you from being overwhelmed and provides solid pivot points as you work through the implementation of the automated tests for each requirement and its 'contexts'. +**Key Rule: Keep Versions Separate** -4. **Use Vendor-Managed Standard Releases:** When setting up a test suite, prioritize using vendor-managed standard releases for software installations and baseline configurations. This should be the starting point for both 'vanilla' and 'hardening' workflows. This approach ensures that your initial and ongoing testing, hardening, and validation closely mirror the real-world usage scenarios of your end-users. +- Never mix requirements from different versions +- Each version represents a distinct security baseline +- Example: Don't combine STIG v2.5 requirements with v3.0 requirements -By adhering to these principles, you ensure that your updates to Benchmark Profiles are consistent, accurate, and aligned with the original guidance documents. \ No newline at end of file +### 2. Completeness Principle + +**Key Rule: All or Nothing** + +- Security benchmarks must include all requirements for a specific version +- Think of it like a recipe - missing ingredients affect the final result +- Example: A Windows 10 STIG profile must implement all controls specified in that version + +### 3. Release Management + +**Key Rule: Meet All Standards** + +- Release readiness is determined by: + - Passing all validation tests + - Meeting security hardening requirements + - Achieving expected thresholds +- Focus on one requirement at a time during development + +### 4. Testing Environment Standards + +**Key Rule: Use Standard Baselines** + +- Start with vendor-managed standard releases +- Test against both: + - Default ("vanilla") configurations + - Hardened configurations +- This ensures real-world applicability + +## Best Practices for Implementation + +1. Document your testing environment +2. Maintain a changelog for each profile version +3. Use version control for tracking changes +4. Test thoroughly before releasing + +## Summary + +Remember: Security benchmarks are complete sets of requirements tied to specific versions. Success comes from methodical implementation and thorough testing against standard baselines. diff --git a/src/courses/profile-dev-test/12.md b/src/courses/profile-dev-test/12.md index e8d422d8e..c4d8ca942 100644 --- a/src/courses/profile-dev-test/12.md +++ b/src/courses/profile-dev-test/12.md @@ -1,20 +1,79 @@ --- order: 12 next: 13.md -title: Creating a `Patch Update` +title: Understanding Profile Patch Updates author: Aaron Lippold --- -## The `Patch Update` Process +## Learning Objectives -A patch update involves making minor changes to a profile to fix issues or improve functionality. Here's a step-by-step guide: +- Understand what constitutes a patch update +- Learn the complete patch update workflow +- Master the testing and validation process -1. **Report the Issue:** Open an issue on our project, detailing the problem and providing examples. Do this on [our issues page](https://github.com/mitre/redhat-enterprise-linux-8-stig-baseline/issues). -2. **Fork and Branch:** Fork the repository on GitHub, then create a branch off the `tagged` patch release you're targeting for the update. -3. **Set Up Testing Suites:** In your forked branch, set up the AWS and Docker testing suites. -4. **Make Updates:** Update the control, `inspec.yml` inputs, thresholds, etc. Don't worry about the InSpec version in the `inspec.yml` - the release process handles that. -5. **Test Your Updates Locally:** Test your updates on all `vanilla` and `hardened` variants of the `known bad` and `known good` states of the `AWS EC2` and `Docker` test targets. Also, test your controls outside perfect conditions to ensure they handle non-optimal target environments. Verify that your update considers the `container`, `virtual machine`, and `1U machine` testing context of applicability. -6. **Lint Your Updates:** Use the `bundle exec rake lint` and `bundle exec rake lint:autocorrect` commands from the test suite to lint your updates. -7. **Commit Your Updates:** After testing and linting, commit your updates to your branch. Include `Fixes #ISSUE` in your commit messages to automatically close the issue when your PR is merged. -8. **Open a PR:** Open a PR on the project repository from your fork. -9. **Check Test Suite:** Ensure the GitHub Action test suite on the project side passes. You can check this at [our actions page](https://github.com/mitre/redhat-enterprise-linux-8-stig-baseline/actions). +## What is a Patch Update? + +A patch update is a minor modification to an InSpec profile that addresses specific issues, bugs, or improvements without changing core functionality. Common examples include: + +- Fixing control logic errors +- Updating threshold values +- Improving error handling +- Adding missing test cases + +## Step-by-Step Patch Update Process + +### 1. Issue Documentation + +- Create a detailed issue in the project repository +- Include specific examples of the problem +- Reference any related documentation +- Link: [Project Issues Page](https://github.com/mitre/redhat-enterprise-linux-8-stig-baseline/issues) + +### 2. Environment Setup + +- Fork the repository +- Create a branch from the target patch release tag +- Configure test environments: + - AWS testing suite + - Docker testing suite + +### 3. Implementation + +- Make necessary updates to: + - Control logic + - `inspec.yml` inputs + - Threshold values +- Note: The InSpec version in `inspec.yml` is managed during release + +### 4. Testing Protocol + +Verify your changes across multiple environments: + +- Vanilla systems +- Hardened systems +- Known bad states +- Known good states +- Edge cases and error conditions + +Test contexts to cover: + +- Container environments +- Virtual machines +- Physical hardware (1U machines) + +### 5. Quality Assurance + +Run the provided linting tools: + +- `bundle exec rake lint` +- `bundle exec rake lint:autocorrect` + +### 6. Commit and PR + +- Commit your updates with a message including `Fixes #ISSUE` +- Open a PR from your fork to the project repository + +### 7. Test Suite Verification + +- Ensure the GitHub Action test suite passes +- Link: [Project Actions Page](https://github.com/mitre/redhat-enterprise-linux-8-stig-baseline/actions) diff --git a/src/courses/profile-dev-test/13.md b/src/courses/profile-dev-test/13.md index 5bd26a58b..42cf4ecd9 100644 --- a/src/courses/profile-dev-test/13.md +++ b/src/courses/profile-dev-test/13.md @@ -1,18 +1,80 @@ --- order: 13 next: 14.md -title: Creating a `Release Update` +title: Understanding Release Updates in SAF author: Aaron Lippold --- -## The `Release Update` Process +## Learning Objectives -A `Release Update` involves creating a new branch, `v#{x}R#{x+1}`, from the current main or latest patch release branch. The `saf generate delta` workflow is then run, which updates the metadata of the `controls`, `inspec.yml`, `README.md`, and other profile elements, while preserving the `describe` and `ruby code logic`. This workflow is detailed in the [Inspec Delta](#2-inspec-delta) section. After the initial commit of the new release branch, follow these steps to keep your work organized: +- Understand what a Release Update is and when it's needed +- Learn the step-by-step process of creating a Release Update +- Master the key components of Release Update management -1. **Track Control IDs:** Create a table of all new `control ids` in the updated benchmark. This can be in CSV, Markdown Table, or in the PR overview information section. This helps track completed and pending work. PRs off the `v#{x}r#{x+1}` can also be linked in the table, especially if using a `micro` vs `massive` PR approach. -2. **Ensure Consistency:** Add 'check box columns' to your tracking table to ensure each requirement of the updated Benchmark receives the same level of scrutiny. -3. **Update CI/CD Process:** Update elements such as the `hardening` content (ansible, puppet, chef, hardened docker images, hardened vagrant boxes) to meet new requirements. Ensure the CI/CD process still functions with the updated elements, preferably on the PR as well. -4. **Update Labels:** Update `titles` and other labels to reflect the updated release number of the Benchmark. -5. **Commit Changes:** Commit these changes to your release branch, ensuring your CI/CD process exits cleanly. -6. **Follow Patch Update Workflow:** With the above in place, follow the 'Patch Update' process, but expect a larger number of requirements to revalidate or update. -7. **Identify Potential Code Changes:** Controls with changes to the `check text` or `fix text` are likely to require `inspec code changes`. If the `check text` and `fix text` of a control remain unchanged, it's likely only a cosmetic update, with no change in the security requirement or validation code. \ No newline at end of file +## What is a Release Update? + +A Release Update is a structured process for updating Security Automation Framework (SAF) profiles to accommodate new benchmark versions. This process ensures consistent quality and maintains traceability of changes. + +## Release Update Workflow + +### Step 1: Branch Creation + +Create a new branch named `v#{x}R#{x+1}` from either: + +- The main branch +- Latest patch release branch + +### Step 2: Generate Delta + +Run the `saf generate delta` workflow to update: + +- Control metadata +- inspec.yml configuration +- README.md documentation +- Other profile elements + +> Note: This process preserves existing `describe` blocks and Ruby code logic + +### Step 3: Change Management + +Follow these best practices to organize your work: + +#### 3.1 Control Tracking + +- Create a tracking table (CSV or Markdown) containing: + - New control IDs + - Status (completed/pending) + - Associated PR links + - Validation checkboxes + +#### 3.2 Quality Assurance Steps + +1. **Validation Checklist** + - [ ] Control requirements reviewed + - [ ] Code changes verified + - [ ] Tests updated + - [ ] Documentation current + +2. **Infrastructure Updates** + - Update hardening content: + - Ansible playbooks + - Puppet modules + - Chef cookbooks + - Docker images + - Vagrant boxes + +3. **Metadata Management** + - Update all version references + - Verify control titles + - Check benchmark labels + +## Tips for Success + +- Focus on controls with modified `check text` or `fix text` +- Unchanged control text typically means no code changes needed +- Use PR links to track changes in your tracking table +- Maintain CI/CD pipeline health throughout updates + +## Next Steps + +After completing these steps, proceed with the Patch Update workflow, keeping in mind that Release Updates typically involve more extensive validation. diff --git a/src/courses/profile-dev-test/14.md b/src/courses/profile-dev-test/14.md index c9d63d32e..50bd5ff2a 100644 --- a/src/courses/profile-dev-test/14.md +++ b/src/courses/profile-dev-test/14.md @@ -1,22 +1,75 @@ --- order: 14 next: 15.md -title: Creating a `Major Version Update` +title: Understanding Major Version Updates author: Aaron Lippold +difficulty: Advanced +prerequisites: + - Basic InSpec knowledge + - Understanding of STIG benchmarks + - Familiarity with Ruby --- -## The `Major Version Update` Process +## Learning Objectives -A `Major Version Update` involves transitioning to a new STIG Benchmark, which introduces a new Rule ID index. This process is more complex than a `Release Update` due to the need for aligning old requirements (Rule IDs) with the new ones. +- Understand what constitutes a Major Version Update and why they occur +- Master the requirement alignment process using multiple identification methods +- Learn to use available tools for version transition +- Develop strategies for efficient code migration +- Implement best practices for version control and testing -For example, when transitioning from RedHat Enterprise Linux 8 v1R12 to Red Hat Enterprise Linux 9 V1R1, the alignment of InSpec tests to the new requirements must be `fuzzy matched`. This involves using common identifiers such as `SRG ID`, `CCIs`, and, if necessary, the `title` and `descriptions`. +## What is a Major Version Update? -This is crucial when a single requirement from the old benchmark is split into multiple requirements in the new benchmark, although this is usually a rare occurrence. +A Major Version Update occurs when transitioning to a new STIG Benchmark version that introduces a completely new Rule ID index. Unlike minor Release Updates, this process requires careful mapping between old and new requirements. -We use a similar process in our [MITRE Vulcan](https://vulcan.mitre.org) to align 'Related Controls' in your Vulcan project to existing published STIG documents. However, the `Delta` tool currently requires manual intervention, and improvements are needed to automate this process. +## Key Concepts -The good news is that **these improvements are within reach**. We can leverage the existing work from `Vulcan` and hopefully soon incorporate these improvements into the SAF `Delta` tool as a direct function. +### Requirement Alignment -Once the 'old controls' and 'new controls' are aligned across 'Rule IDs', you can migrate the InSpec / Ruby code into their respective places. +:::tip 💡 **Pro Tip**: Create a spreadsheet to track your requirement mappings during the alignment process. +::: -Then, you follow the same setup, CI/CD organization, and control update process as in the `Release Update` process and hopfully finding that the actual InSpec code from the previous benchmark is very close to the needed InSpec code for the same 'requirement' in the new Benchmark. +When moving between major versions (e.g., RHEL 8 v1R12 to RHEL 9 V1R1), we need to align existing tests with new requirements using: + +- SRG IDs (Security Requirements Guide IDs) +- CCIs (Control Correlation Identifiers) +- Titles and descriptions when necessary + +### The Alignment Process + +1. **Initial Analysis** + - Compare old and new benchmark requirements + - Identify matching controls using common identifiers + - Note any split or merged requirements + +2. **Using Available Tools** + - MITRE Vulcan assists in alignment process + - Current Delta tool requires manual verification + - Future automation improvements are in development + +3. **Code Migration** + - Transfer InSpec/Ruby code to new requirement locations + - Verify control mappings + - Update test code as needed + +### Practical Example + +Consider this simplified alignment scenario: + +## Best Practices + +- Document all requirement mappings +- Verify control alignments thoroughly +- Test extensively after migration + +## What's Next + +After alignment is complete, follow the standard Release Update process for: + +- Setting up CI/CD +- Organizing controls +- Updating and testing requirements + +## Summary + +Major Version Updates require careful attention to requirement alignment and code migration. While tools like Vulcan help, some manual verification is still needed. Future improvements will streamline this process. diff --git a/src/courses/profile-dev-test/15.md b/src/courses/profile-dev-test/15.md index ee85de3d7..7b634b18f 100644 --- a/src/courses/profile-dev-test/15.md +++ b/src/courses/profile-dev-test/15.md @@ -1,29 +1,60 @@ --- order: 15 next: 16.md -title: Test Kitchen +title: Understanding Test Kitchen author: Aaron Lippold --- -## Test Kitchen - Getting Started +## Learning Objectives -[Test Kitchen](http://kitchen.ci) is a robust tool for testing infrastructure code and software on isolated platforms. It provides a consistent, reliable environment for developing and testing infrastructure code. +By the end of this module, you will be able to: -## Workflow Defined by our Test Kitchen Files +- Understand the purpose and benefits of Test Kitchen +- Describe the Test Kitchen workflow +- Differentiate between vanilla and hardened configurations +- Execute basic Test Kitchen commands -Test Kitchen's workflow involves building out suites and platforms using its drivers and provisioners. It follows a create, converge, verify, and destroy cycle: +## What is Test Kitchen? -1. **Create:** Test Kitchen creates an instance of the platform. -2. **Converge:** It applies the infrastructure code to the instance. -3. **Verify:** It checks if the instance is in the desired state. -4. **Destroy:** It destroys the instance after testing. +Test Kitchen is a powerful testing framework that allows developers to test infrastructure code across different platforms and configurations. Think of it as a laboratory where you can safely experiment with different system configurations without affecting your production environment. -In our testing workflow, we have defined four test suites to test different deployment patterns in two configurations - `vanilla` and `hardened`. +## Test Kitchen Workflow -- `vanilla`: This represents a completely stock installation of the testing target, as provided by the product vendor, with no configuration updates beyond what is 'shipped' by the vendor. Apart from the standard Test Kitchen initialization, the system is considered 'stock'. -- `hardened`: This configuration is set up using the `driver` section of the Test Kitchen suite and is executed during the `converge` phase. The `hardened` configuration represents the final `target configuration state` of our test instance, adhering to the recommended configuration of the Benchmark we are working on. For example, it aligns as closely as possible with the Red Hat Enterprise Linux V1R12 recommendations. +The testing process follows four key stages: -For more details on Test Kitchen's workflow, refer to the [official documentation](http://kitchen.ci/docs/getting-started/). +1. **Create** 🏗️ + - Spins up a fresh instance of your target platform + - Sets up the basic environment + +2. **Converge** 🔄 + - Applies your infrastructure code + - Configures the instance according to your specifications + +3. **Verify** ✅ + - Runs your tests against the instance + - Checks if everything is configured correctly + +4. **Destroy** 🧹 + - Cleans up the test environment + - Removes the instance completely + +## Testing Configurations + +We use two main testing configurations: + +### Vanilla Configuration + +- Stock installation with default settings +- No customization or hardening +- Represents "out-of-the-box" state +- Used as a baseline for comparison + +### Hardened Configuration + +- Implements security best practices +- Follows benchmark recommendations (e.g., RHEL V1R12) +- Represents the target secure state +- Applied during the converge phase ```journey Test Kitchen Workflow section Setup @@ -49,6 +80,11 @@ For more details on Test Kitchen's workflow, refer to the [official documentatio -## Test Kitchen's Modifications to Targets +## Behind the Scenes: System Access + +To enable testing, Test Kitchen makes minimal system modifications: -Test Kitchen makes minor modifications to the system to facilitate initialization and access. It adds a 'private ssh key' for the default user and sets up primary access to the system for this user using the generated key. Test Kitchen uses the 'platform standard' for access - SSH for Unix/Linux systems and WinRM for Windows systems. \ No newline at end of file +- Adds SSH private key authentication +- Sets up appropriate access protocols: + - SSH for Unix/Linux systems + - WinRM for Windows systems diff --git a/src/courses/profile-dev-test/16.md b/src/courses/profile-dev-test/16.md index 543e799be..0dc021f15 100644 --- a/src/courses/profile-dev-test/16.md +++ b/src/courses/profile-dev-test/16.md @@ -1,15 +1,41 @@ --- order: 16 next: 17.md -title: Test Kitchen - Create +title: Test Kitchen - Understanding the Create Stage author: Aaron Lippold index: true --- ## Test Kitchen Create Stage -The `create` stage in Test Kitchen sets up testing environments. It uses standard and patched images from AWS and Red Hat, including AMI EC2 images, Docker containers, and Vagrant boxes. +### What is the Create Stage? -Test Kitchen automatically fetches the latest images from sources like Amazon Marketplace, DockerHub, Vagrant Marketplace, and Bento Hub. You can customize this to use different images, private repositories (like Platform One's Iron Bank), or local images. +The `create` stage is a fundamental part of Test Kitchen that prepares your testing environments. Think of it as setting up your test laboratory where you'll run your security tests. -For more details on how Test Kitchen manages images, visit the [Test Kitchen website](https://kitchen.ci). You can also refer to the GitHub documentation for the `kitchen-ec2`, `kitchen-vagrant`, `kitchen-sync`, and [`kitchen-inspec`](https://github.com/inspec/kitchen-inspec) project on GitHub. \ No newline at end of file +### How it Works + +Test Kitchen handles environment creation by: + +- Fetching pre-configured system images +- Setting up virtual machines or containers +- Preparing the environment for testing + +### Supported Platforms + +Test Kitchen works with various platforms: + +- AWS EC2 instances (using AMIs) +- Docker containers +- Vagrant boxes +- Red Hat Enterprise Linux systems + +### Image Sources + +Test Kitchen automatically pulls from: + +- Amazon Marketplace +- DockerHub +- Vagrant Cloud +- Bento Box Repository +- Custom repositories (e.g., Platform One's Iron Bank) +- Local image storage diff --git a/src/courses/profile-dev-test/17.md b/src/courses/profile-dev-test/17.md index a4ada43d6..9aff7d368 100644 --- a/src/courses/profile-dev-test/17.md +++ b/src/courses/profile-dev-test/17.md @@ -6,28 +6,82 @@ author: Aaron Lippold index: true --- +## Learning Objectives + +By the end of this section, you will understand: + +- The purpose and function of Test Kitchen's converge stage +- How to use different infrastructure configurations +- The differences between vanilla and hardened environments + ## Test Kitchen Converge Stage -The `converge` stage uses Ansible Playbooks from the Ansible Lockdown project to apply hardening configurations, specifically the RHEL8-STIG playbook, and RedHat managed containers. +The `converge` stage applies system configurations using infrastructure as code (IaC) tools. This crucial stage transforms your environment from a base state to your desired configuration. -## EC2 and Vagrant Converge +> **Key Concept**: Think of the converge stage as "applying your recipe" - it takes your raw ingredients (base system) and follows your instructions to create the final dish (configured system). -For EC2 and Vagrant, we use 'wrapper playbooks' for the 'vanilla' and 'hardened' suites. +Supported configuration tools include: -- The 'vanilla' playbook establishes a basic test environment. -- The 'hardened' playbook applies the 'vanilla role' and the Ansible Lockdown RHEL8-STIG role to the 'hardened' target, using Ansible Galaxy, a `requirements.txt`, and Ansible Roles. +- Ansible Playbooks (used in this course) +- Puppet +- Chef +- Terraform +- Shell scripts -Some tasks in the hardening role were disabled for automated testing, but this doesn't significantly impact our security posture. We can still meet our validation and thresholds. +## EC2 and Vagrant Converge -For more on using these playbooks, running Ansible, or modifying the playbooks, roles, and tasks, see the Ansible Project Website. +We implement two distinct configurations using 'wrapper playbooks': -Find these roles and 'wrapper playbooks' in the [spec/](./spec/) directory. +1. **Vanilla Environment** + - Purpose: Establishes baseline test environment + - Implementation: Basic configuration playbook + +2. **Hardened Environment** + - Purpose: Creates security-enhanced environment + - Components: + - Base vanilla configuration + - RHEL8-STIG security controls + - Ansible Galaxy dependencies + - Custom roles and requirements + +> **Note**: While some hardening tasks are disabled for testing, this doesn't compromise our security validation goals. ## Container Converge -We use RedHat vendor images for both the `vanilla` and `hardened` containers. +Our container strategy utilizes two RedHat UBI8 (Universal Base Image) variants: + +1. **Vanilla Container** + +This container uses the `registry.access.redhat.com/ubi8/ubi:8.9-1028` image from RedHat's community repositories. + +It represents a standard, out-of-the-box configuration. + +- Community maintained +- Standard configuration + +1. **Hardened Container** +hardened: This container uses the `registry1.dso.mil/ironbank/redhat/ubi/ubi8` image from Red Hat's Platform One Iron Bank project. + +It represents a security-enhanced configuration. + +- STIG-compliant +- Regular security updates +- Platform One certified + +## Hands-on Practice + +Try these exercises: + +1. Compare the contents of vanilla and hardened playbooks +2. Identify key security configurations in the RHEL8-STIG role +3. Examine the wrapper playbook structure in the spec/ directory + +### Summary -- **`vanilla`:** This container uses the `registry.access.redhat.com/ubi8/ubi:8.9-1028` image from RedHat's community repositories. -- **`hardened`:** This container uses the `registry1.dso.mil/ironbank/redhat/ubi/ubi8` image from Red Hat's Platform One Iron Bank project. +- Converge stage implements your desired system configurations +- Multiple implementation tools available (Ansible, Puppet, Chef, etc.) +- Two primary configurations: vanilla (baseline) and hardened (security-enhanced) +- Container implementations use RedHat UBI8 images with different security postures -The Iron Bank UBI8 image is regularly patched, updated, and hardened according to STIG requirements. +::: info Next Steps: Practice running the converge stage with both vanilla and hardened configurations to understand the differences in outcomes. +::: diff --git a/src/courses/profile-dev-test/18.md b/src/courses/profile-dev-test/18.md index 1c623eca5..02b48d4fa 100644 --- a/src/courses/profile-dev-test/18.md +++ b/src/courses/profile-dev-test/18.md @@ -8,10 +8,26 @@ index: true ## Test Kitchen Validate Stage -The `verify` stage uses the `kitchen-inspec` verifier from Test Kitchen to run the profile against the test targets. +The `verify` stage uses the `kitchen-inspec` verifier from Test Kitchen to run the inspec profile against the test targets. -For this stage, the profile receives a set of tailored `input` YAML files. These files adjust the testing for each target, ensuring accurate validation against the expected state and minimizing false results. +For this stage, the inspec profile receives a set of tailored `input` YAML files. These files adjust the testing for each target, ensuring accurate validation against the expected state and minimizing false results. + +They are located at the root of the project and are named something like `kitchen.inputs.yml`. There are also specific `threshold` files for each target environment platform (EC2, container, and Vagrant) in both the `vanilla` and `hardened` suites. -The following sections provide a detailed breakdown of these files, their structure, and the workflow organization. \ No newline at end of file +These establish the expected or allowed thresholds for vanilla and hardened configurations. Sometimes, we also have specific thresholds for hardened container or DISA EC2 vanilla configurations to allow for different hardening configurations that may be part of the test suite. + +### Key Points to Remember + +- **Input Files**: Customize tests for each target environment. +- **Threshold Files**: Define acceptable limits for different configurations. +- **Platform-Specific Settings**: Ensure accurate validation across various platforms. + +### Practical Tips + +- Always review and update input files to match the target environment. +- Verify threshold settings to ensure they align with your security requirements. +- Regularly test across different platforms to catch environment-specific issues. +- Use the `kitchen verify` command to run the tests and validate the configurations. +- Limit the control verify is running by using the `INSPEC_CONTROL` environment variable. diff --git a/src/courses/profile-dev-test/19.md b/src/courses/profile-dev-test/19.md index 7fb8a7a41..08e0f12d0 100644 --- a/src/courses/profile-dev-test/19.md +++ b/src/courses/profile-dev-test/19.md @@ -11,7 +11,14 @@ The `destroy` stage terminates the EC2 instances, Vagrant boxes, or containers t Occasionally, the `destroy` stage may encounter issues if the hosting platforms have altered the state of the provisioned instance during your writing, testing, or debugging sessions. If you face any problems with the `destroy` stage or any other Test Kitchen commands, verify the following: -- The test target's login, hostname, and IP address are still accurate. -- The test instance is still running on the hosting platforms. +- Ensure the test target's login credentials, hostname, and IP address are still accurate. +- Confirm that the test instance is still running on the hosting platform. -Sometimes, the solution can be as simple as checking if the instance is still active. \ No newline at end of file +Sometimes, the solution can be as simple as checking if the instance is still active. + +### Additional Tips for Troubleshooting + +- **Check Logs**: Review the Test Kitchen logs for any error messages or clues about what might be going wrong. +- **Manual Cleanup**: If the `destroy` command fails, you may need to manually terminate the instances through your cloud provider's console or command-line tools. +- **Update Configurations**: Ensure that your `.kitchen.yml` configuration file is up-to-date and correctly references the instances you are trying to destroy. +- **Network Issues**: Verify that there are no network issues preventing Test Kitchen from communicating with the instances. diff --git a/src/courses/profile-dev-test/20.md b/src/courses/profile-dev-test/20.md index fc22727c3..45ace5336 100644 --- a/src/courses/profile-dev-test/20.md +++ b/src/courses/profile-dev-test/20.md @@ -1,10 +1,24 @@ --- order: 20 next: 21.md -title: Test Kitchen - .kitchen/ directory +title: Test Kitchen - .kitchen/ Directory author: Aaron Lippold --- ## The `.kitchen/` Directory -The [`.kitchen/`](/.kitchen/) directory contains the state file for Test Kitchen, which is automatically generated when you first run Test Kitchen. Refer to the [Finding Your Test Target Login Details](#311-locating-test-target-login-details) section to see how you can use the `.kitchen/` directory. +The [`.kitchen/`](/.kitchen/) directory contains the state files for Test Kitchen. These files are automatically generated when you first run Test Kitchen. + +### Understanding the `.kitchen/` Directory + +The `.kitchen/` directory is crucial for managing the state of your Test Kitchen instances. It includes configuration and state information that Test Kitchen uses to manage your test environments. + +### Using the `.kitchen/` Directory + +Refer to the [Finding Your Test Target Login Details](#311-locating-test-target-login-details) section to learn how to use the `.kitchen/` directory effectively. This section will guide you on locating and utilizing the login details for your test targets stored within this directory. + +### Key Points to Remember + +- The `.kitchen/` directory is automatically created when you run Test Kitchen for the first time. +- It stores state and configuration files necessary for managing test environments. +- Understanding the contents of this directory can help you troubleshoot and manage your test instances more effectively. diff --git a/src/courses/profile-dev-test/21.md b/src/courses/profile-dev-test/21.md index 19075f8d7..08250aaa0 100644 --- a/src/courses/profile-dev-test/21.md +++ b/src/courses/profile-dev-test/21.md @@ -9,9 +9,9 @@ author: Aaron Lippold The [`kitchen.yml`](./kitchen.yml) file is the primary configuration file for Test Kitchen. It outlines the shared configuration for all your testing environments, platforms, and the testing framework to be used. -Each of the subsequent kitchen files will inherit the shared settings from this file automatlly and merge them with the setting in the child kitchen file. +Each of the subsequent kitchen files will inherit the shared settings from this file automatically and merge them with the settings in the child kitchen file. -## Example `kitchen.yml` file +## Example `kitchen.yml` File ```yaml --- @@ -41,7 +41,7 @@ suites: playbook: spec/ansible/roles/ansible-role-rhel-hardened.yml ``` -# Breakdown of the `kitchen.yml` file: +# Breakdown of the `kitchen.yml` file ```yaml verifier: @@ -97,4 +97,4 @@ The workflow of Test Kitchen involves the following steps: 1. **Create:** Test Kitchen uses the driver to create an instance of the platform. 2. **Converge:** Test Kitchen uses the provisioner to apply the infrastructure code to the instance. In this case, it's using Ansible playbooks. 3. **Verify:** Test Kitchen uses the verifier to check if the instance is in the desired state. -4. **Destroy:** Test Kitchen uses the driver to destroy the instance after testing. This is not shown in your file. \ No newline at end of file +4. **Destroy:** Test Kitchen uses the driver to destroy the instance after testing. This is not shown in your file. diff --git a/src/courses/profile-dev-test/22.md b/src/courses/profile-dev-test/22.md index 6f5885953..46d0f2d61 100644 --- a/src/courses/profile-dev-test/22.md +++ b/src/courses/profile-dev-test/22.md @@ -9,11 +9,11 @@ author: Aaron Lippold The `kitchen.ec2.yml` file is instrumental in setting up our testing targets within the AWS environment. It outlines the configuration details for these targets, including their VPC assignments and the specific settings for each VPC. -This file leverages the ` AWS CLI and AWS Credentials` configured as described in the previous [Required Software](#13-required-software) section. +This file leverages the `AWS CLI and AWS Credentials` configured as described in the previous [Required Software](#13-required-software) section. Alternatively, if you've set up AWS Environment Variables, the file will use those for AWS interactions. -## Example `kitchen.ec2.yml` file +## Example `kitchen.ec2.yml` File ```yaml --- @@ -115,4 +115,4 @@ The workflow of Test Kitchen involves the following steps: 3. **Verify:** Test Kitchen checks if the instance is in the desired state. This is not shown in your file, but it would be configured in the `verifier` section. 4. **Destroy:** Test Kitchen uses the driver to destroy the instance after testing. This is not shown in your file, but it would be configured in the `driver` section. -The `transport` is used in all these steps to communicate with the instance. \ No newline at end of file +The `transport` is used in all these steps to communicate with the instance. diff --git a/src/courses/profile-dev-test/23.md b/src/courses/profile-dev-test/23.md index e540604c4..6abc9ae40 100644 --- a/src/courses/profile-dev-test/23.md +++ b/src/courses/profile-dev-test/23.md @@ -7,7 +7,7 @@ author: Aaron Lippold ## Understanding the [`kitchen.container.yml`](./kitchen.container.yml) -The `kitchen.container.yml` file orchestrates our container-based test suite. It defines two types of containers, hardened and vanilla, and specifies the inspec_tests to run against them. It also configures the generation and storage of test reports. +The `kitchen.container.yml` file orchestrates our container-based test suite. It defines two types of containers: hardened and vanilla, and specifies the InSpec tests to run against them. It also configures the generation and storage of test reports. Unlike other test suites, the container suite skips the 'provisioner' stage for the vanilla and hardened targets. Instead, during the create stage, it simply downloads and starts the specified images. This is due to the use of the [dummy Test Kitchen driver](https://github.com/test-kitchen/test-kitchen/blob/main/lib/kitchen/driver/dummy.rb), which is ideal for interacting with pre-configured or immutable targets like containers. @@ -48,7 +48,7 @@ suites: # creds_file: './creds.json' ``` -# Breakdown of the `kitchen.container.yml` file: +# Breakdown of the `kitchen.container.yml` file ```yaml provisioner: @@ -117,4 +117,4 @@ The `kitchen.container.yml` file uses the following environment variables to sel - `VANILLA_CONTAINER_IMAGE`: This variable specifies the Docker container image considered 'not hardened'. - default: `registry.access.redhat.com/ubi8/ubi:8.9-1028` - `HARDENED_CONTAINER_IMAGE`: This variable specifies the Docker container image considered 'hardened'. - - default: `registry1.dso.mil/ironbank/redhat/ubi/ubi8` \ No newline at end of file + - default: `registry1.dso.mil/ironbank/redhat/ubi/ubi8` diff --git a/src/courses/profile-dev-test/24.md b/src/courses/profile-dev-test/24.md index 6fda8f8c3..42e35d0a8 100644 --- a/src/courses/profile-dev-test/24.md +++ b/src/courses/profile-dev-test/24.md @@ -7,7 +7,7 @@ author: Aaron Lippold ## GitHub Actions -Our profile utilizes GitHub Actions as its primary CI/CD process. The Actions are separated by general business or process functions, allowing for a clear distinction between the workflow stages that we are testing in our workflow. +Our profile utilizes GitHub Actions as its primary CI/CD process. The Actions are separated by general business or process functions, allowing for a clear distinction between the workflow stages that we are testing. ### [`lint-profile.yml`](.github/workflows/lint-profile.yml) @@ -29,10 +29,10 @@ This action performs the following steps: ### [`verify-container.yml`](.github/workflows/verify-container.yml) -This action performs similar steps to `verify-ec2.yml`, but with some differences: +This action performs similar steps to `verify-ec2.yml`, with some differences: -1. It configures access to the required container registries - Platform One and Red Hat. +1. Configures access to the required container registries - Platform One and Red Hat. ### [`verify-vagrant.yml.example`](.github/workflows/verify-vagrant.yml.example) -This action is similar to the `verify-ec2` workflow, but instead of using a remote AWS EC2 instance in a VPC, it uses a local Vagrant virtual machine as the test target. The user can configure whether to upload the results to our Heimdall Demo server or not by modifing the Github Action. \ No newline at end of file +This action is similar to the `verify-ec2` workflow, but instead of using a remote AWS EC2 instance in a VPC, it uses a local Vagrant virtual machine as the test target. The user can configure whether to upload the results to our Heimdall Demo server or not by modifying the GitHub Action. diff --git a/src/courses/profile-dev-test/25.md b/src/courses/profile-dev-test/25.md index c17d86e4c..fcfdc9d91 100644 --- a/src/courses/profile-dev-test/25.md +++ b/src/courses/profile-dev-test/25.md @@ -12,7 +12,11 @@ author: Aaron Lippold Before running Delta, it's beneficial to format the profile to match the format Delta will use. This minimizes changes to only those necessary based on the guidance update. Follow these steps: -1. **Run Cookstyle:** Install the Cookstyle gem and use it to lint the controls into Cookstyle format. Verify the gem installation with `gem list cookstyle`. Create a `.rubocop.yml` file with the provided example settings or modify these settings via the command line. Run `cookstyle -a ./controls` and any tests you have for your profile. +1. **Run Cookstyle:** + + - **Install Cookstyle:** Install the Cookstyle gem by running `gem install cookstyle`. Verify the installation with `gem list cookstyle`. + - **Create Configuration:** Create a `.rubocop.yml` file with the provided example settings or modify these settings via the command line. + - **Lint Controls:** Run `cookstyle -a ./controls` to lint the controls into Cookstyle format. Also, run any tests you have for your profile to ensure everything is working correctly. ```shell AllCops: @@ -63,4 +67,7 @@ Lint/AmbiguousBlockAssociation: Enabled: false ``` -2. **Run the SAF CLI Command:** Use `saf generate update_controls4delta` to check and update the control IDs with the provided XCCDF guidance. This process checks if the new guidance changes the control numbers and updates them if necessary. This minimizes the Delta output content and improves the visualization of the modifications provided by the Delta process. +2. Run the SAF CLI Command: + +- Use the command: `saf generate update_controls4delta` to check and update the control IDs with the provided XCCDF guidance. +- Verify Changes: This process checks if the new guidance changes the control numbers and updates them if necessary. This minimizes the Delta output content and improves the visualization of the modifications provided by the Delta process. diff --git a/src/courses/profile-dev-test/26.md b/src/courses/profile-dev-test/26.md index e4f602575..bd7e3b0ab 100644 --- a/src/courses/profile-dev-test/26.md +++ b/src/courses/profile-dev-test/26.md @@ -2,14 +2,14 @@ order: 26 next: 27.md title: InSpec Delta - Making the Delta Release Branch -shortTitle: Delta - Making your Branch +shortTitle: Delta - Making Your Branch author: Aaron Lippold --- -## Prepair Your Environment +## Prepare Your Environment -- **Download New Guidance:** Download the appropriate profile from the [DISA Document Library](https://public.cyber.mil/stigs/downloads/). Unzip the downloaded folder and identify the `xccdf.xml` file. -- **Create the InSpec Profile JSON File:** Clone or download the InSpec profile locally. Run the `inspec json` command to create the InSpec Profile JSON file to be used in the `saf generate delta` command. +- **Download New Guidance:** Download the appropriate profile from the [DISA Document Library](https://public.cyber.mil/stigs/downloads/). Unzip the downloaded folder and locate the `xccdf.xml` file. +- **Create the InSpec Profile JSON File:** Clone or download the InSpec profile locally. Run the `inspec json` command to create the InSpec Profile JSON file, which will be used in the `saf generate delta` command. ## Delta Workflow Process @@ -17,7 +17,7 @@ author: Aaron Lippold ## Using Delta -The SAF InSpec Delta workflow typically involves two phases, `preformatting` and `delta`. +The SAF InSpec Delta workflow typically involves two phases: `preformatting` and `delta`. Before starting, ensure you have the latest SAF-CLI, the InSpec Profile JSON file, and the updated guidance file. @@ -31,9 +31,9 @@ For more information on these commands, refer to the following documentation: ## Scope of Changes by Delta -Delta focuses on specific modifications migrating the changes from the XCCDF Benchmark Rules to the Profiles controls, and updating the 'metadata' of each of thosin the `control ID`, `title`, `default desc`, `check text`, and `fix text`, between the XCCDF Benchmark Rules and the Profile Controls. +Delta focuses on specific modifications, migrating the changes from the XCCDF Benchmark Rules to the Profile's controls, and updating the 'metadata' of each control, including `control ID`, `title`, `default desc`, `check text`, and `fix text`, between the XCCDF Benchmark Rules and the Profile Controls. -If the XCCDF Guidance Document introduces a new 'Rule' or `inspec control` that is not in the current profile's `controls` directory, Delta will add it to the controls directory, populating the metadata from the XCCDF Benchmark data, similar to the [inspec_profile](#inspec-profile) (aliases xccdf-benchmark-to-inspec-stubs) tool. +If the XCCDF Guidance Document introduces a new 'Rule' or `inspec control` that is not in the current profile's `controls` directory, Delta will add it to the controls directory, populating the metadata from the XCCDF Benchmark data, similar to the [inspec_profile](#inspec-profile) tool. It also adjusts the `tags` and introduces a `ref` between the `impact` and `tags`. @@ -44,4 +44,3 @@ Delta does not modify the Ruby/InSpec code within the control, leaving it intact - The original Delta branch can be found [here](https://github.com/mitre/saf/pull/485). - Delta moves lines not labeled with 'desc' to the bottom, between tags and InSpec code. - Whether the controls are formatted to be 80 lines or not, Delta exhibits the same behavior with the extra text. -- Parameterizing should be considered. diff --git a/src/courses/profile-dev-test/27.md b/src/courses/profile-dev-test/27.md index cdb6f62fb..95d6f10bf 100644 --- a/src/courses/profile-dev-test/27.md +++ b/src/courses/profile-dev-test/27.md @@ -6,13 +6,13 @@ shortTitle: Tips & Troubleshooting author: Aaron Lippold --- -## Tips, Tricks and Troubleshooting +## Tips, Tricks, and Troubleshooting ### Test Kitchen #### Locating Test Target Login Details -Test Kitchen stores the current host details of your provisioned test targets in the `.kitchen/` directory. Here, you'll find a `yml` file containing your target's `hostname`, `ip address`, `host details`, and login credentials, which could be an `ssh pem key` or another type of credential. +Test Kitchen stores the current host details of your provisioned test targets in the `.kitchen/` directory. Here, you'll find a `yml` file containing your target's `hostname`, `IP address`, host details, and login credentials, which could be an `SSH PEM key` or another type of credential. ```shell .kitchen @@ -28,11 +28,11 @@ Test Kitchen stores the current host details of your provisioned test targets in #### Restoring Access to a Halted or Restarted Test Target -If your test target reboots or updates its network information, you don't need to execute bundle exec kitchen destroy. Instead, update the corresponding .kitchen/#{suite}-#{target}.yml file with the updated information. This will ensure that your kitchen login, kitchen validate, and other kitchen commands function correctly, as they'll be connecting to the correct location instead of using outdated data. +If your test target reboots or updates its network information, you don't need to execute `bundle exec kitchen destroy`. Instead, update the corresponding `.kitchen/#{suite}-#{target}.yml` file with the new information. This ensures that your `kitchen login`, `kitchen validate`, and other kitchen commands function correctly by connecting to the correct location instead of using outdated data. -#### AWS Console and EC2 Oddities +#### AWS Console and EC2 Considerations -Since we're using the free-tier for our AWS testing resources instead of a dedicated host, your test targets might shut down or 'reboot in the background' if you stop interacting with them, halt them, put them in a stop state, or leave them overnight. To regain access, edit the .kitchen/#{suite}-#{target}.yml file. As mentioned above, there's no need to recreate your testing targets if you can simply point Test Kitchen to the correct IP address. +Since we're using the free tier for our AWS testing resources instead of a dedicated host, your test targets might shut down or reboot in the background if you stop interacting with them, halt them, put them in a stop state, or leave them overnight. To regain access, edit the `.kitchen/#{suite}-#{target}.yml` file with the updated IP address. As mentioned above, there's no need to recreate your testing targets if you can simply point Test Kitchen to the correct IP address. ## InSpec / Ruby @@ -46,13 +46,13 @@ When developing InSpec controls, it's beneficial to use the `kitchen-test` suite 2. Then, insert `binding.pry` at the point in your code where you want to start debugging. 3. When you run your tests, execution will stop at the `binding.pry` line, and you can inspect variables, step through the code, and more. -***!Pro Tip!*** +***Pro Tip*** -- Remember to remove or comment out the `binding.pry` lines when you're done debugging or you won't have a good 'linting' down the road. +- Remember to remove or comment out the `binding.pry` lines when you're done debugging, or you may encounter issues with linting tools. ### Streamlining Your Testing with `inspec shell` -The `inspec shell` command allows you to test your full control update on your test target directly. To do this, you'll need to retrieve the IP address and SSH PEM key for your target instance from the Test Kitchen `.kitchen` directory. For more details on this, refer to the [Finding Your Test Target Login Details](#311-locating-test-target-login-details) section. +The `inspec shell` command allows you to test your full control update on your test target directly. To do this, you'll need to retrieve the IP address and SSH PEM key for your target instance from the Test Kitchen `.kitchen` directory. For more details on this, refer to the [Locating Test Target Login Details](#locating-test-target-login-details) section. Once you have your IP address and SSH PEM key (for AWS target instances), or the container ID (for Docker test instances), you can use the following commands: @@ -61,4 +61,4 @@ Once you have your IP address and SSH PEM key (for AWS target instances), or the ### Using `kitchen login` for Easy Test Review and Modification -The `kitchen login` command provides an easy way to review and modify your test target. This tool is particularly useful for introducing test cases, exploring corner cases, and validating both positive and negative test scenarios. +The `kitchen login` command allows you to access your test target's command line directly. This is particularly useful for introducing test cases, exploring edge cases, and validating both positive and negative test scenarios. By interacting directly with the test environment, you can deepen your understanding of how your controls perform in real-world conditions. diff --git a/src/courses/profile-dev-test/28.md b/src/courses/profile-dev-test/28.md index edc8506b6..c14072f31 100644 --- a/src/courses/profile-dev-test/28.md +++ b/src/courses/profile-dev-test/28.md @@ -11,20 +11,20 @@ author: Aaron Lippold #### Evolution of STIGs and Security Benchmarks -The Department of Defense (DOD) has continually updated its databases that track rules and Security Technical Implementation Guides (STIGs) that house those rules. +The Department of Defense (DoD) has continually updated its databases that track rules and the Security Technical Implementation Guides (STIGs), which define those rules. Initially, the system was known as the Vulnerability Management System (VMS). -In the STIGs, you might come across data elements that are remnants from these iterations. These include `Group Title` (gid or gtitle), `Vulnerability ID` (VulnID), `Rule ID` (rule_id), `STIG ID` (stig_id), and others. +In the STIGs, you might come across data elements that are remnants from previous systems. These include `Group Title` (`gid` or `gtitle`), `Vulnerability ID` (`VulnID`), `Rule ID` (`rule_id`), `STIG ID` (`stig_id`), and others. -A significant change was the shift from using `STIG ID` to `Rule ID` in many security scanning tools. This change occurred because the Vulnerability Management System used the STIG_ID as the primary index for the requirements in each Benchmark in VMS. +A significant change was the shift from using `STIG ID` to `Rule ID` in many security scanning tools. This change occurred because the VMS used the `STIG_ID` as the primary index for the requirements in each benchmark. -However, when DISA updated the Vendor STIG Processes and replaced the VMS, they decided to migrate the primary ID from the STIG ID to the Rule ID, tracking changes in the Rules as described above. +However, when DISA updated the vendor STIG processes and replaced the VMS, they decided to migrate the primary ID from the `STIG ID` to the `Rule ID`, tracking changes in the rules. -Examples of tools that still use either fully or in part the 'STIG ID' vs the 'Rule ID' as a primary index are: the DISA STIG Viewer, Nessus Audit Scans, and Open SCAP client. +Examples of tools that still use the `STIG ID`, either fully or partially, as a primary index include the DISA STIG Viewer, Nessus Audit Scans, and OpenSCAP client. -While these elements might seem confusing, understanding their historical context is essential. +Understanding the historical context of these elements is essential, even if they might seem confusing. -In our modern profiles, some data from the XCCDF Benchmarks still exist in the document but are not used or rendered in the modern InSpec Profiles. However, in some of the older profiles, you may see many of these data elements as `tags` in the profile. The intention was to ensure easy and lossless conversion between XCCDF Benchmark and HDF Profile. +Although some data from the XCCDF benchmarks still exist in our modern profiles, they are not used or rendered in modern InSpec profiles. The intention was to ensure easy and lossless conversion between XCCDF benchmarks and HDF profiles. -It was later realized that since the structure of these data elements was 'static', they could be easily reintroduced when converting back to an XCCDF Benchmark. Therefore, rendering them in the profile was deemed unnecessary. +It was later realized that since the structure of these data elements was static, they could be easily reintroduced when converting back to an XCCDF benchmark. Therefore, including them in the profile was deemed unnecessary. diff --git a/src/courses/profile-dev-test/29.md b/src/courses/profile-dev-test/29.md index 0e970ff0b..e5fbb4fb9 100644 --- a/src/courses/profile-dev-test/29.md +++ b/src/courses/profile-dev-test/29.md @@ -7,16 +7,16 @@ author: Aaron Lippold ## Terms & Definitions - **Baseline**: This refers to a set of relevant security controls, such as NIST 800-53 controls or Center for Internet Security Controls. These controls offer high-level security best practices, grouped into common areas of concern. -- **Benchmark**: This is a set of security controls tailored to a specific type of application or product. These controls are typically categorized into 'high', 'medium', and 'low' levels based on Confidentiality, Integrity, and Availability (C.I.A). -- **[Common Correlation Identifier](https://public.cyber.mil/stigs/cci/) (CCI)**: The Control Correlation Identifier (CCI) provides a standard identifier and description for each of the singular, actionable statements that comprise an IA control or IA best practice. For example: 'CCI-000366'. -- **Group Title (gtitle)**: This is essentially the SRG ID but is a holdover data value from the old Vulnerability Management System. For example: 'SRG-OS-000480-GPOS-00227'. -- **Major Version Update**: These are updates that occur when a software vendor releases a new major version of their product's STIG, e.g., RedHat releasing version 9 of Red Hat Enterprise Linux or Microsoft releasing a new major version of Windows. -- **Patch Update**: These are regular updates that address missing corner cases of testing for one or more benchmark requirements, or improvements to the InSpec code for a requirement. These updates result in a new patch release of the benchmark, e.g., `v1.12.4` to `v1.12.5`. +- **Benchmark**: This is a set of security controls tailored to a specific type of application or product. These controls are typically categorized into 'high', 'medium', and 'low' levels based on their impact on Confidentiality, Integrity, and Availability (C.I.A). +- **[Control Correlation Identifier](https://public.cyber.mil/stigs/cci/) (CCI)**: The Control Correlation Identifier provides a standard identifier and description for each individual, actionable statement that comprises an Information Assurance (IA) control or best practice. For example: 'CCI-000366'. +- **Group Title (gtitle)**: This is essentially the SRG ID but is a legacy value from the old Vulnerability Management System. For example: 'SRG-OS-000480-GPOS-00227'. +- **Major Version Update**: These updates occur when a software vendor releases a new major version of their product, resulting in a new major version of the corresponding STIG. For example, Red Hat releasing version 9 of Red Hat Enterprise Linux or Microsoft releasing a new major version of Windows. +- **Patch Update**: These are regular updates that address edge cases in testing for one or more benchmark requirements or improvements to the InSpec code for a requirement. These updates result in a new patch release of the benchmark, e.g., `v1.12.4` to `v1.12.5`. - **Profile**: This is a set of tests representing a STIG or a CIS Benchmark. These tests automate the validation of a system against that STIG or CIS Benchmark. - **Release Update**: These are updates that occur when the STIG Benchmark owner releases an updated version of the STIG, e.g., Red Hat Enterprise Linux V1R12 to V1R13. -- **Rule ID (rid)**: The Rule ID has two parts separated by the `r` in the string - ('SV-230221) and (r858734_rule)'. The first part remains unique within the major version of a Benchmark document, while the latter part of the string is updated each time the 'Rule' is updated 'release to release' of the Benchmark. For example: 'SV-230221r858734_rule'. -- **Security Requirements Guide (SRG)**: SRG documents provide generalized security guidance in XCCDF format that applies to a 'class' of software products such as 'web server', 'operating systems', 'application servers' or 'databases'. You can find an archive of these at the DISA STIG [Document Library](https://public.cyber.mil/stigs/downloads/). -- **Security Technical Implementation Guide (STIG)**: This is a set of specific technical actions required to establish a certain security posture for a software product. It is based on a desired Security Requirements Guide that applies to the product's software class and function, such as operating system, web server, database, etc. You can find an archive of these at the DISA STIG [Document Library](https://public.cyber.mil/stigs/downloads/). +- **Rule ID (rid)**: The Rule ID has two parts separated by the `r` in the string—for example, 'SV-230221' and 'r858734_rule'. The first part remains unique within the major version of a benchmark document, while the latter part is updated each time the rule is updated with each release of the benchmark. For example: 'SV-230221r858734_rule'. +- **Security Requirements Guide (SRG)**: SRG documents provide generalized security guidance in XCCDF format that applies to a class of software products such as web servers, operating systems, application servers, or databases. You can find these at the DISA STIG [Document Library](https://public.cyber.mil/stigs/downloads/). +- **Security Technical Implementation Guide (STIG)**: This is a set of specific technical actions required to establish a certain security posture for a software product. It is based on the relevant Security Requirements Guide that applies to the product's software class and function, such as operating systems, web servers, or databases. Archives are available at the DISA STIG [Document Library](https://public.cyber.mil/stigs/downloads/). - **SRG_ID**: This is the unique identifier of the SRG requirement. These indexes, like the STIG Rule IDs, also show their parent-child relationship. For example: 'SRG-OS-000480-GPOS-00227'. -- **STIG ID (stig_id)**: Many testing tools and testing results tools use this ID - vs the Rule ID - to display each of the individual results of a Benchmark validation run. For example: 'RHEL-08-010000'. Examples include: DISA STIG Viewer, Nessus Audit Scans and the Open SCAP client. -- **XCCDF Benchmark (XCCDF or XCCDF Benchmark)**: XCCDF (Extensible Configuration Checklist Description Format) is a standard developed by NIST and DOD to provide a machine-readable XML format for creating security guidance documents and security technical implementation guides. You can find an archive of these at the DISA STIG [Document Library](https://public.cyber.mil/stigs/downloads/). +- **STIG ID (stig_id)**: Many testing and result analysis tools use this ID—versus the Rule ID—to display each of the individual results of a benchmark validation run. For example: 'RHEL-08-010000'. Examples include DISA STIG Viewer, Nessus Audit Scans, and the OpenSCAP client. +- **XCCDF Benchmark**: XCCDF (Extensible Configuration Checklist Description Format) is a standard developed by the National Institute of Standards and Technology (NIST) and the Department of Defense (DoD) to provide a machine-readable XML format for creating security guidance documents and Security Technical Implementation Guides. Archives are available at the DISA STIG [Document Library](https://public.cyber.mil/stigs/downloads/). From 3043ac6d4a0268785bc866bdb7119b3909e8330a Mon Sep 17 00:00:00 2001 From: Amndeep Singh Mann Date: Mon, 9 Dec 2024 11:25:23 -0800 Subject: [PATCH 03/27] readme/pg 1 Signed-off-by: Amndeep Singh Mann --- src/courses/profile-dev-test/README.md | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/courses/profile-dev-test/README.md b/src/courses/profile-dev-test/README.md index 348b20072..09db9f566 100644 --- a/src/courses/profile-dev-test/README.md +++ b/src/courses/profile-dev-test/README.md @@ -1,7 +1,7 @@ --- order: 1 next: 02.md -title: Development & Testing InSpec Profile +title: 1. Developing & Testing InSpec Profiles author: Aaron Lippold --- @@ -46,7 +46,7 @@ The development and testing of profiles are accomplished using a variety of tool - **Test Kitchen**: Integration testing framework - Example: `kitchen test` validates your InSpec profiles - Use case: Automated compliance testing -- **Docker/Podman**: Container platforms +- **Docker/Podman**: Container runtime platforms - Example: `docker run` creates isolated test environments - Use case: Consistent testing across platforms - **InSpec**: Compliance testing framework @@ -60,7 +60,9 @@ The development and testing of profiles are accomplished using a variety of tool Our development and testing workflow is managed by Test Kitchen. This tool is integral to our GitHub Actions CI/CD Pipelines and is also used for local development, testing, and releasing updates, patches, and full releases of the profile. -> 💡 **Pro Tip**: When starting out, focus on Docker-based testing before moving to AWS environments. +::: tip Walk before you run! +When starting out, focus on Docker-based testing before moving to AWS environments. +::: ### Testing Environments @@ -68,15 +70,19 @@ Test Kitchen uses Docker (or Podman, if preferred) and AWS (using free-tier reso ### Platform One Integration -Additionally, Test Kitchen uses the Red Hat hardened `ubi8 base container` from Platform One for testing. To test the hardened container portion of the testing suite, you'll need to set up and log in to your P1 Free account, then obtain a CLI token to pull the Platform One Iron Bank Red Hat Enterprise Linux 8 Universal Base Image (P1 IB UBI8) image into the test suite. +Additionally, Test Kitchen uses images from Platform One during the hardened container test of the testing suite. In order for you to use them as well, you'll need to set up and log in to your P1 account (free but requires registration), then obtain a CLI token to pull the Platform One Iron Bank images into the test suite. -> ⚠️ **Important**: Ensure you keep your P1 CLI token secure and never commit it to version control. +::: important Secrets should be secret! +Ensure you keep your P1 CLI token secure and never commit it to version control. +::: ## Getting Started with Examples This guide refers to the [MITRE RedHat Enterprise Linux 8 STIG](https://github.com/mitre/redhat-enterprise-linux-8-stig-baseline/tree/metzger_dynamic_inputs) profile, which provides a working example of the workflow described here. -> 🔍 **Note**: Development happens in the `main` branch, with stable versions available as tagged releases. +::: note Development vs Releases +Development happens in the `main` branch, with stable versions available as tagged releases. +::: ### Hands-on Practice From 534686a2ba469459ab45d22d49b5164d114bf216 Mon Sep 17 00:00:00 2001 From: Amndeep Singh Mann Date: Mon, 9 Dec 2024 13:59:57 -0800 Subject: [PATCH 04/27] pg 2 Signed-off-by: Amndeep Singh Mann --- src/courses/profile-dev-test/02.md | 85 ++++++++++++++++++------------ 1 file changed, 50 insertions(+), 35 deletions(-) diff --git a/src/courses/profile-dev-test/02.md b/src/courses/profile-dev-test/02.md index edc4efad7..18d5648a1 100644 --- a/src/courses/profile-dev-test/02.md +++ b/src/courses/profile-dev-test/02.md @@ -1,7 +1,7 @@ --- order: 2 next: 03.md -title: Understanding Repository Organization +title: 2. Understanding Repository Organization author: Aaron Lippold --- @@ -15,25 +15,60 @@ By the end of this section, you will: ## Repository Structure Overview -The repository uses a structured branching and tagging strategy to manage STIG profile versions and updates. This organization ensures reliable tracking of changes and stable releases for production use. +The InSpec profile repository should have a structured branching and tagging strategy to manage STIG profile versions and updates. This organizational strategy ensures reliable tracking of changes and stable releases for production use. ## Branch Strategy -### Main Branch +Security developers and engineers should be putting actively developed changes and updates into feature branches. Once those feature branches have been completed and peer reviewed, they should be merged into the version branch for the respective guidance release. Once all required features, changes, bugfixes, etc. have been merged in, a release should be created - this means that the version branch should be merged into your main branch and a tag should be created. The main branch of the repository ought to be the latest, working version of the codebase. + +::: tip Branches are not releases +Sometimes code ends up merged directly to the main branch - this is fine - the main branch is not a formal release. +::: + + + + + + + + + + + + + + + + + + + + + + + + + + +
Main BranchVersion Branch (`v{x}r{xx}`)
PurposeActive development and testingWork-in-progress tracking a major STIG benchmark release
ContainsLatest code and patches

Code that is becoming aligned to an official guidance release

DISA usually releases updates to STIGs on a quarterly basis. See the [DISA STIG Document Library](https://public.cyber.mil/stigs/downloads/).

Example branch name`main` or `master``v1r12` for Version 1, Release 12
+ +## Version Control and Tagging Strategy + +### Tags + +#### Current Tag + +We do not recommend using a `current` or `latest` tag - if someone needs the latest and greatest, they can pull directly from the main branch of the repository. + +#### Major Tags + +Major tags point to the latest patch releases of the benchmark. For example, `v1`, `v1.3`, and `v1.3.0` all should point at the same commit representing the first release of the Red Hat Enterprise Linux 8 STIG V1R3 Benchmark. The `v1.12.xx` tag(s) would represent the V1R12 Benchmark releases as we find bugs, fixes, or general improvements to the testing profile. + +#### Patch Releases -- Purpose: Active development and testing -- Contains: Latest code and patches -- Best for: Development and testing workflows -- Note: For production, use stable releases instead - -### Version Branches (`v{x}r{xx}`) - -- Purpose: Track major STIG benchmark releases -- Example: `v1r12` for Version 1, Release 12 -- Aligns with: Official DISA STIG releases -- Reference: [DISA STIG Document Library](https://public.cyber.mil/stigs/downloads/) +The latest patch release always points to the major release for the profile. -## Version Control Strategy +For example, after releasing `v1.12.0`, we will point `v1.12` to that patch release: `v1.12.0`. When an issue is found, we will fix, tag, and release `v1.12.1`. We will then 'move' the `v1.12` tag so that it points to tag `v1.12.1`. This way, your pipelines can choose if they want to pin on a specific release of the InSpec profile or always run using the latest code on the main branch. ### Semantic Versioning (SemVer) @@ -42,23 +77,3 @@ Format: `MAJOR.RELEASE.PATCH` - MAJOR: Matches STIG version - RELEASE: Matches STIG release - PATCH: Profile updates between STIG releases - -Example timeline: - -## Tags - -### Current Tag - -We don't use a specific `current` or `latest` tag. The `current`/`latest` tag for the profile and repository will always be the latest major tag of the benchmark. For example, if `v1.12.3` is the latest Benchmark release from the STIG author, then the tag `v1.12` will point to the `v1.12.3` release of the code. - -To use the current `main`, point directly to the GitHub repo. - -### Major Tags - -Major tags point to the latest patch release of the benchmark. For example, `v1.3` and `v1.3.0` represent the first release of the Red Hat Enterprise Linux 8 STIG V1R3 Benchmark. The `v1.12.xx` tag(s) would represent the V1R12 Benchmark releases as we find bugs, fixes, or general improvements to the testing profile. This tag will point to its `v{x}r{xx}` counterpart. - -## Patch Releases - -The latest patch release always points to the major release for the profile. - -For example, after releasing `v1.12.0`, we will point `v1.12` to that patch release: `v1.12.0`. When an issue is found, we will fix, tag, and release `v1.12.1`. We will then 'move' the `v1.12` tag so that it points to tag `v1.12.1`. This way, your pipelines can choose if they want to pin on a specific release of the InSpec profile or always run 'current'. From 71489a993fac864bfb226bb1d5e77519b8bb6976 Mon Sep 17 00:00:00 2001 From: Amndeep Singh Mann Date: Mon, 9 Dec 2024 14:31:28 -0800 Subject: [PATCH 05/27] pg 3 Signed-off-by: Amndeep Singh Mann --- src/courses/profile-dev-test/03.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/courses/profile-dev-test/03.md b/src/courses/profile-dev-test/03.md index d1177be71..bdb2a7602 100644 --- a/src/courses/profile-dev-test/03.md +++ b/src/courses/profile-dev-test/03.md @@ -1,11 +1,11 @@ --- order: 3 next: 04.md -title: Environment Setup Guide +title: 3. Environment Setup Guide author: Aaron Lippold --- -## Prerequisites Knowledge +## Prerequisite Knowledge - Basic command line experience - Familiarity with package managers @@ -37,7 +37,7 @@ Create accounts with these services before proceeding: 3. **P1 Harbor Access** - Purpose: Container registry access - - Get token: [Harbor Login](https://login.dso.mil/auth/realms/baby-yoda/protocol/openid-connect/auth?client_id=harbor) + - Get CLI token from your user account page: [Harbor Login](https://login.dso.mil/auth/realms/baby-yoda/protocol/openid-connect/auth?client_id=harbor) ## Environment Configuration @@ -45,7 +45,7 @@ Create accounts with these services before proceeding: Important variables that control testing behavior: -- `INSPEC_CONTROL`: Specifies which single control to run in the `bundle exec kitchen verify` phase, useful for testing and debugging a single requirement. +- `INSPEC_CONTROL`: Specifies which single control to run in the `bundle exec kitchen verify` phase - useful for testing and debugging a single requirement. - default: `none` - `KITCHEN_LOCAL_YAML`: Specifies the target testing environment you want to use to run and validate the profile. - default: `none` From f5573e84855db2dbb8d667ab2d4dd612a3a42b49 Mon Sep 17 00:00:00 2001 From: Amndeep Singh Mann Date: Tue, 10 Dec 2024 22:53:24 -0800 Subject: [PATCH 06/27] pg 4 and 5 Signed-off-by: Amndeep Singh Mann --- src/courses/profile-dev-test/04.md | 2 +- src/courses/profile-dev-test/05.md | 72 ++++++++++++++++-------------- 2 files changed, 40 insertions(+), 34 deletions(-) diff --git a/src/courses/profile-dev-test/04.md b/src/courses/profile-dev-test/04.md index e203b5e0b..47f44f531 100644 --- a/src/courses/profile-dev-test/04.md +++ b/src/courses/profile-dev-test/04.md @@ -1,7 +1,7 @@ --- order: 4 next: 05.md -title: Test your Test Environment +title: 4. Test your Test Environment author: Aaron Lippold --- diff --git a/src/courses/profile-dev-test/05.md b/src/courses/profile-dev-test/05.md index ab96b28ff..a0788827a 100644 --- a/src/courses/profile-dev-test/05.md +++ b/src/courses/profile-dev-test/05.md @@ -1,13 +1,15 @@ --- order: 5 next: 06.md -title: AWS Testing Suite +title: 5. AWS Testing Suite author: Aaron Lippold --- ## AWS Testing Setup -> -> Note: This guide assumes basic familiarity with AWS. If you're new to AWS, please review the [AWS Getting Started Guide](https://aws.amazon.com/getting-started/) first. + +:::note +This guide assumes basic familiarity with AWS. If you're new to AWS, please review the [AWS Getting Started Guide](https://aws.amazon.com/getting-started/) first. +::: 1. Configure your AWS CLI and set up your AWS credentials - If you haven't installed AWS CLI, [download it here](https://aws.amazon.com/cli/) @@ -31,13 +33,17 @@ author: Aaron Lippold ``` ## Running Through the AWS Test Suite -> -> Understanding the Test Workflow: -> -> - **Vanilla**: Represents an unmodified baseline system -> - **Hardened**: Represents a system with security controls applied -7. List the kitchen instances with: `bundle exec kitchen list`. You should see something like this: +::: important Understanding the Test Workflow: +`vanilla` represents an unmodified baseline system while `hardened` represents a system with security controls applied. +::: + +7. List the kitchen instances: +```bash + bundle exec kitchen list +``` + +You should see something like this: ```shell Instance Driver Provisioner Verifier Transport Last Action Last Error @@ -53,10 +59,10 @@ author: Aaron Lippold bundle exec kitchen create vanilla ``` - > This step launches a fresh EC2 instance for testing +Executing that line launches a fresh EC2 instance for testing: ```shell -➜ redhat-enterprise-linux-8-stig-baseline git:(main*)bundle exec kitchen create vanilla +➜ redhat-enterprise-linux-8-stig-baseline git:(main*) bundle exec kitchen create vanilla -----> Starting Test Kitchen (v3.5.1) -----> Creating ... < OTHER OUTPUT > @@ -70,10 +76,10 @@ author: Aaron Lippold bundle exec kitchen converge vanilla ``` - > Convergence applies the necessary configurations to prepare the system for testing +Convergence applies the necessary configurations to prepare the system for testing: ```shell -➜ redhat-enterprise-linux-8-stig-baseline git:(main*)bundle exec kitchen converge vanilla +➜ redhat-enterprise-linux-8-stig-baseline git:(main*) bundle exec kitchen converge vanilla -----> Starting Test Kitchen (v3.5.1) NOTICE - Installing needed packages Updating Subscription Management repositories. @@ -88,10 +94,16 @@ author: Aaron Lippold -----> Test Kitchen is finished. (1m13.52s) ``` -10. Run InSpec on the kitchen instance: `bundle exec kitchen verify`. +10. **Verify** that the Kitchen instance meets our requirements by using InSpec: + +```bash +bundle exec kitchen verify +``` + +You'll see the same InSpec CLI output that we've gotten familiar with in our other classes: ```shell - ➜ redhat-enterprise-linux-8-stig-baseline git:(main*)bundle exec kitchen verify vanilla + ➜ redhat-enterprise-linux-8-stig-baseline git:(main*) bundle exec kitchen verify vanilla -----> Starting Test Kitchen (v3.5.1) -----> Setting up ... Finished setting up (0m0.00s). @@ -111,27 +123,21 @@ author: Aaron Lippold -----> Test Kitchen is finished. (0m6.62s) ``` +11. **Destroy** the Kitchen instance: + +```bash +bundle exec kitchen destroy vanilla +``` + +::: caution 💸 +Always remember to pause or destroy your test instances after testing to avoid unnecessary AWS charges. You can do it via `kitchen` or by going into the AWS Console. +::: + ### Analyzing Results - Results Location: `./spec/results/rhel-8_*` - Use [Heimdall Lite](https://heimdall-lite.mitre.org) to compare results: - 1. Load both `hardened` and `vanilla` results - 2. Compare to verify expected failures and passes + 1. Load both the `vanilla` and `hardened` results + 2. Use the `Comparison View` (look for the toggle underneath the files list after selecting the hamburger menu in the top left) to compare the results sets and verify expected passes and failures 3. Review corner cases for complete coverage -::: tip Always remember to pause or destroy your test instances after testing to avoid unnecessary AWS charges: -> -> ```bash -> bundle exec kitchen destroy vanilla -> ``` -> -> ```sh -> Pause your instance in the AWS Console -> ``` -> -::: - -1. Destroy the kitchen instance: `bundle exec kitchen destroy vanilla`. -2. For steps that apply to making updates, patches, and updates to the profile, see the next section, [Updating the Profile](#18-updating-the-profile). -3. Your InSpec scan results are located in the `./spec/results/` directory, named `./spec/results/rhel-8_*`. -4. Use [Heimdall Lite](https://heimdall-lite.mitre.org "MITRE Heimdall Lite") to load both the `hardened` and `vanilla` results to ensure your changes and updates, "failed as expected and passed as expected and covered your corner cases." From 31d8a3b3d061636500c0313824718a004a2b436e Mon Sep 17 00:00:00 2001 From: Amndeep Singh Mann Date: Tue, 10 Dec 2024 23:37:42 -0800 Subject: [PATCH 07/27] pg 6 Signed-off-by: Amndeep Singh Mann --- src/courses/profile-dev-test/05.md | 4 ++- src/courses/profile-dev-test/06.md | 58 ++++++++++++++++++++---------- 2 files changed, 43 insertions(+), 19 deletions(-) diff --git a/src/courses/profile-dev-test/05.md b/src/courses/profile-dev-test/05.md index a0788827a..f1bbfc018 100644 --- a/src/courses/profile-dev-test/05.md +++ b/src/courses/profile-dev-test/05.md @@ -97,7 +97,7 @@ Convergence applies the necessary configurations to prepare the system for testi 10. **Verify** that the Kitchen instance meets our requirements by using InSpec: ```bash -bundle exec kitchen verify +bundle exec kitchen verify vanilla ``` You'll see the same InSpec CLI output that we've gotten familiar with in our other classes: @@ -133,6 +133,8 @@ bundle exec kitchen destroy vanilla Always remember to pause or destroy your test instances after testing to avoid unnecessary AWS charges. You can do it via `kitchen` or by going into the AWS Console. ::: +12. Repeat these steps but replace `vanilla` with `hardened`. + ### Analyzing Results - Results Location: `./spec/results/rhel-8_*` diff --git a/src/courses/profile-dev-test/06.md b/src/courses/profile-dev-test/06.md index e46d84fd6..a0dd4e31b 100644 --- a/src/courses/profile-dev-test/06.md +++ b/src/courses/profile-dev-test/06.md @@ -1,7 +1,7 @@ --- order: 6 next: 07.md -title: Testing with Docker Containers +title: 6. Testing with Docker Containers author: Aaron Lippold --- @@ -33,26 +33,36 @@ Before running tests, configure your environment: Set these environment variables: ```shell -> export KITCHEN_LOCAL_YAML=kitchen.container.yml -> export VANILLA_CONTAINER_IMAGE=registry.access.redhat.com/ubi8/ubi:8.9-1028 -> export HARDENED_CONTAINER_IMAGE=registry1.dso.mil/ironbank/redhat/ubi/ubi8 -> (optional) export INSPEC_CONTROL='SV-230222' +export KITCHEN_LOCAL_YAML=kitchen.container.yml +export VANILLA_CONTAINER_IMAGE=registry.access.redhat.com/ubi8/ubi:8.9-1028 +export HARDENED_CONTAINER_IMAGE=registry1.dso.mil/ironbank/redhat/ubi/ubi8 +(optional) export INSPEC_CONTROL='SV-230222' ``` +Here we will be assessing vanilla and hardened container images. While many containers are hosted by Docker themselves on their [Docker Hub](https://hub.docker.com/) platform, organizations often deploy their own container registries. Red Hat makes their registry available at [`registry.access.redhat.com`](https://registry.access.redhat.com) - we will be using their [`ubi8` image](https://developers.redhat.com/blog/2019/10/09/what-is-red-hat-universal-base-image#high_quality__the_security_and_operational_benefits_of_rhel). Iron Bank is Platform One's hardened container image repository and is available at [`registry1.dso.mil`](https://registry1.dso.mil) - they publish a version of the `ubi8` container that they claim is more hardened than Red Hat's baseline. Let's use Red Hat's `ubi8` as the vanilla container image and Iron Bank's `ubi8` as the hardened container image and validate Iron Bank's claim of having a more hardened image! + ## Running Through the Docker Test Suite -1. List the kitchen instances with: `bundle exec kitchen list` +1. List the kitchen instances with: + +```bash +bundle exec kitchen list +``` ```shell -➜ redhat-enterprise-linux-8-stig-baseline git:(main*)bundle exec kitchen list +➜ redhat-enterprise-linux-8-stig-baseline git:(main*) bundle exec kitchen list Instance Driver Provisioner Verifier Transport Last Action Last Error vanilla-ubi8 Dokken Dummy Inspec Dokken hardened-ubi8 Dokken Dummy Inspec Dokken ``` -2. Create the kitchen instance: `bundle exec kitchen create vanilla` +2. Create the kitchen instance: +```bash +bundle exec kitchen create vanilla +``` ```shell +➜ redhat-enterprise-linux-8-stig-baseline git:(main*) bundle exec kitchen create vanilla -----> Starting Test Kitchen (v3.5.1) -----> Creating ... Creating kitchen sandbox at /Users/alippold/.dokken/kitchen_sandbox/de2da32d73-vanilla-ubi8 @@ -63,10 +73,13 @@ hardened-ubi8 Dokken Dummy Inspec Dokken -----> Test Kitchen is finished. (0m1.77s) ``` -3. Converge the kitchen instance: `bundle exec kitchen converge vanilla` +3. Converge the kitchen instance: +```bash +bundle exec kitchen converge vanilla +``` ```shell -➜ redhat-enterprise-linux-8-stig-baseline git:(main*)bundle exec kitchen converge vanilla +➜ redhat-enterprise-linux-8-stig-baseline git:(main*) bundle exec kitchen converge vanilla -----> Starting Test Kitchen (v3.5.1) -----> Converging ... ... @@ -74,9 +87,13 @@ hardened-ubi8 Dokken Dummy Inspec Dokken -----> Test Kitchen is finished. (0m0.88s) ``` -4. Run InSpec on the kitchen instance: `bundle exec kitchen verify vanilla` +4. Run InSpec on the kitchen instance: +```bash +bundle exec kitchen verify vanilla +``` ```shell +➜ redhat-enterprise-linux-8-stig-baseline git:(main*) bundle exec kitchen verify vanilla -----> Starting Test Kitchen (v3.5.1) -----> Verifying ... Loaded redhat-enterprise-linux-8-stig-baseline @@ -93,7 +110,18 @@ Profile Summary: 0 successful controls, 1 control failure, 0 controls skipped Test Summary: 0 successful, 4 failures, 0 skipped ``` -## This is not the **Error** Your Looking For, move along +5. Repeat these steps but replace `vanilla` with `hardened`. + +### Analyzing Results + +- Results Location: `./spec/results/rhel-8_*` +- Use [Heimdall Lite](https://heimdall-lite.mitre.org) to compare results: + 1. Load both the `vanilla` and `hardened` results + 2. Use the `Comparison View` (look for the toggle underneath the files list after selecting the hamburger menu in the top left) to compare the results sets and verify expected passes and failures + 3. Review corner cases for complete coverage + + +## This isn't the error you're looking for, move along The error below is just Test Kitchen telling you that not all of the `controls` of the profile passed. @@ -106,9 +134,3 @@ The error below is just Test Kitchen telling you that not all of the `controls` >>>>>> Please see .kitchen/logs/kitchen.log for more details >>>>>> Also try running `kitchen diagnose --all` for configuration ``` - -## Next Steps - -1. For steps that apply to making updates, patches, and updates to the profile, see the next section, [Updating the Profile](#updating-the-profile). -2. Your InSpec scan results are located in the `./spec/results/` directory, named `./spec/results/ubi-8_*.` -3. Use Heimdall Lite to load both the `hardened` and `vanilla` results to ensure your changes and updates, "failed as expected and passed as expected and covered your corner cases." From 0acf0b84a4ea0ef8a769f4b858fa0b5fb2b22b4d Mon Sep 17 00:00:00 2001 From: Amndeep Singh Mann Date: Tue, 10 Dec 2024 23:57:29 -0800 Subject: [PATCH 08/27] pg 7 Signed-off-by: Amndeep Singh Mann --- src/courses/profile-dev-test/07.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/courses/profile-dev-test/07.md b/src/courses/profile-dev-test/07.md index 819aee9c4..b68dbfd4b 100644 --- a/src/courses/profile-dev-test/07.md +++ b/src/courses/profile-dev-test/07.md @@ -1,7 +1,7 @@ --- order: 7 next: 08.md -title: Pull Request Strategies - Choosing Your Approach +title: 7. Pull Request Strategies - Choosing Your Approach author: Aaron Lippold --- @@ -9,11 +9,11 @@ author: Aaron Lippold By the end of this section, you will: -- Understand GitFlow workflow for repository management +- Understand the GitHub Flow workflow for repository management - Compare micro and macro PR approaches - Learn when to use different PR strategies -## GitFlow Overview +## GitHub Flow Overview This project uses the [GitHub Flow](https://docs.github.com/en/get-started/quickstart/github-flow) model for managing changes. This workflow helps maintain code quality and collaboration through systematic pull requests (PRs). @@ -102,4 +102,8 @@ Consider these scenarios and decide which PR strategy you would use: 1. What are the key differences between micro and macro PRs? 2. Which PR strategy would you choose for a critical security patch? -3. How does GitFlow support different PR strategies? +3. How does GitHub Flow support different PR strategies? + +::: tip Why not both? +One approach is to have the small feature branches get merged into a version branch on successful review following the "Micro PR" approach. Then you can do a more holistic review of the macro PR associated with the version branch focusing more on having a consistent coding style, ensuring no duplicate `input`s got created, identifying InSpec controls that weren't modified when similar ones were, etc. Once the version branch is approved, it can be merged into the main branch and a release can be cut. +::: From dc6e632a023b9e11596ae3b87f4bb98986ad7e66 Mon Sep 17 00:00:00 2001 From: Amndeep Singh Mann Date: Wed, 11 Dec 2024 00:06:54 -0800 Subject: [PATCH 09/27] pg 8 Signed-off-by: Amndeep Singh Mann --- src/courses/profile-dev-test/08.md | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/courses/profile-dev-test/08.md b/src/courses/profile-dev-test/08.md index e26f9135a..9e16f4f0f 100644 --- a/src/courses/profile-dev-test/08.md +++ b/src/courses/profile-dev-test/08.md @@ -1,13 +1,13 @@ --- order: 8 next: 09.md -title: Security Benchmarks vs Traditional Software +title: 8. Security Benchmarks vs Traditional Software author: Aaron Lippold --- ## Understanding Security Benchmarks -## Key Differences from Traditional Software +### Key Differences from Traditional Software Security benchmarks differ from traditional software development in several critical ways: @@ -19,24 +19,26 @@ Security benchmarks differ from traditional software development in several crit - Each benchmark version is a complete, standalone entity - InSpec profiles must match their corresponding benchmark version exactly -## Development Approaches +### Development Approaches Two common approaches to benchmark development: - **Micro Approach**: Gradual, incremental development -- **Massive Approach**: Complete implementation in larger chunks +- **Macro Approach**: Complete implementation in larger chunks -> 💡 **Key Point**: Both approaches are valid - choose based on your team's workflow preferences. +::: tip Both approaches are valid +Choose an approach or combination thereof that is based on your team's workflow preferences. +::: -## Version Control Best Practices +### Version Control Best Practices -### Working with Branches +#### Working with Branches -- ⚠️ Never work directly on 'main' +- Never work directly on 'main' - Always fork from the latest release - Consider 'main' or 'development' branches as pre-release candidates -## Practical Exercise +### Practical Exercise Try answering these questions: @@ -44,5 +46,6 @@ Try answering these questions: 2. How should you handle new requirements that arise between releases? 3. What branch strategy would you use for a new benchmark version? ---- -**Remember**: Security benchmark validation is binary - it either meets all requirements or it doesn't. +::: important Security benchmark validation is binary +The benchmark validation either meets all requirements or it doesn't. It being an accurate, representative assessment (and thereby useful to others) requires that it be the former. +::: From 84503226324b06bee8f1fa05b2c8eba8e8b9eeaa Mon Sep 17 00:00:00 2001 From: Amndeep Singh Mann Date: Wed, 11 Dec 2024 00:51:31 -0800 Subject: [PATCH 10/27] pg 9 Signed-off-by: Amndeep Singh Mann --- src/courses/profile-dev-test/09.md | 49 ++++++++++++++++++------------ 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/src/courses/profile-dev-test/09.md b/src/courses/profile-dev-test/09.md index d4d4e2942..485c8860a 100644 --- a/src/courses/profile-dev-test/09.md +++ b/src/courses/profile-dev-test/09.md @@ -17,25 +17,36 @@ By the end of this section, you will be able to: Security benchmark profiles require regular updates to maintain their effectiveness. Let's explore the three main types of updates: -### 1. Patch Updates (Minor Changes) - -- Frequency: Weekly to monthly -- Purpose: Address corner cases and improve testing code -- Version Change Example: v1.12.4 → v1.12.5 -- Typical Changes: Bug fixes, code improvements, test coverage expansion - -### 2. Release Updates (Intermediate Changes) - -- Triggered by: STIG Benchmark owner releases -- Example: RHEL STIG V1R12 → V1R13 -- Includes: New security requirements, updated controls - -### 3. Major Version Updates - -- Triggered by: New product versions -- Examples: - - RHEL 8 → RHEL 9 - - Windows Server 2019 → Windows Server 2022 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Patch UpdatesRelease UpdatesMajor Version Updates
ScopeMinorIntermediateIntermediate/Significant
TriggerThe validation code author desiring to address corner cases, fix bugs, or otherwise improve the quality of the tests.Guidance author making a new release of the benchmark to address new security requirements or update metadata such as the associated controls.The guidance author is significantly overhauling their nomenclature or requirement identification schema. Alternatively, a new major version of the software system is being released which would require a new version of the benchmark to address the potentially significant implementation changes - though in this case, guidance authors sometimes choose to create a new benchmark entirely.
ExampleAn InSpec control did not properly address a caveat specified by the guidance. Making the fix bumps the profile from v1.3.4 to v1.3.5.DISA publishes a new version of the RHEL 8 STIG going from V1R13 to V1R14 in order to adjust the check text command syntax for several sshd configuration related requirements amongst other things. Making the changes bumps the profile from v1.13.4 to v1.14.0.DISA adds, removes, and modifies a substantial number of controls due to transitioning between control versions (NIST SP 800-53 Rev. 4 to Rev. 5). Making the changes bumps the profile from v1.6.1 to v2.0.0.
## Understanding Update Scope From 955f16bbb9c9a760b17a306cca7df50379912e68 Mon Sep 17 00:00:00 2001 From: Amndeep Singh Mann Date: Wed, 11 Dec 2024 00:54:29 -0800 Subject: [PATCH 11/27] pg 9 - forgot to update title so it has a number Signed-off-by: Amndeep Singh Mann --- src/courses/profile-dev-test/09.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/courses/profile-dev-test/09.md b/src/courses/profile-dev-test/09.md index 485c8860a..b7b845390 100644 --- a/src/courses/profile-dev-test/09.md +++ b/src/courses/profile-dev-test/09.md @@ -1,7 +1,7 @@ --- order: 9 next: 10.md -title: Understanding Profile Updates +title: 9. Understanding Profile Updates author: Aaron Lippold --- From 28ceec692336fb4ba4fe3acc71d99e6400aa871f Mon Sep 17 00:00:00 2001 From: Amndeep Singh Mann Date: Wed, 11 Dec 2024 00:57:28 -0800 Subject: [PATCH 12/27] clarified language pg 9 Signed-off-by: Amndeep Singh Mann --- src/courses/profile-dev-test/09.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/courses/profile-dev-test/09.md b/src/courses/profile-dev-test/09.md index b7b845390..561fe6dc4 100644 --- a/src/courses/profile-dev-test/09.md +++ b/src/courses/profile-dev-test/09.md @@ -36,8 +36,8 @@ Security benchmark profiles require regular updates to maintain their effectiven Trigger The validation code author desiring to address corner cases, fix bugs, or otherwise improve the quality of the tests. - Guidance author making a new release of the benchmark to address new security requirements or update metadata such as the associated controls. - The guidance author is significantly overhauling their nomenclature or requirement identification schema. Alternatively, a new major version of the software system is being released which would require a new version of the benchmark to address the potentially significant implementation changes - though in this case, guidance authors sometimes choose to create a new benchmark entirely. + Guidance author making a new release of the benchmark to address new or updated security requirements. + The guidance author is significantly overhauling their nomenclature, requirement identification schema, or control alignment. Alternatively, a new major version of the software system is being released which would require a new version of the benchmark to address the potentially significant implementation changes - though in this case, guidance authors sometimes choose to create a new benchmark entirely. Example From 43be27b74a1c97df0e50e9bc70dad0d2feb481ee Mon Sep 17 00:00:00 2001 From: Amndeep Singh Mann Date: Wed, 11 Dec 2024 00:58:31 -0800 Subject: [PATCH 13/27] ahhhhhhhhh Signed-off-by: Amndeep Singh Mann --- src/courses/profile-dev-test/09.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/courses/profile-dev-test/09.md b/src/courses/profile-dev-test/09.md index 561fe6dc4..9e046c754 100644 --- a/src/courses/profile-dev-test/09.md +++ b/src/courses/profile-dev-test/09.md @@ -43,7 +43,7 @@ Security benchmark profiles require regular updates to maintain their effectiven Example An InSpec control did not properly address a caveat specified by the guidance. Making the fix bumps the profile from v1.3.4 to v1.3.5. DISA publishes a new version of the RHEL 8 STIG going from V1R13 to V1R14 in order to adjust the check text command syntax for several sshd configuration related requirements amongst other things. Making the changes bumps the profile from v1.13.4 to v1.14.0. - DISA adds, removes, and modifies a substantial number of controls due to transitioning between control versions (NIST SP 800-53 Rev. 4 to Rev. 5). Making the changes bumps the profile from v1.6.1 to v2.0.0. + DISA adds, removes, and modifies a substantial number of requirements due to transitioning between control versions (NIST SP 800-53 Rev. 4 to Rev. 5). Making the changes bumps the profile from v1.6.1 to v2.0.0. From 52d06c355b515b0fbd974432451d2352ca0b97f6 Mon Sep 17 00:00:00 2001 From: Amndeep Singh Mann Date: Wed, 11 Dec 2024 13:10:10 -0800 Subject: [PATCH 14/27] pg 10 Signed-off-by: Amndeep Singh Mann --- src/courses/profile-dev-test/10.md | 179 +++++++++++++++++++++++++---- 1 file changed, 155 insertions(+), 24 deletions(-) diff --git a/src/courses/profile-dev-test/10.md b/src/courses/profile-dev-test/10.md index a3a19a342..8ee0f2464 100644 --- a/src/courses/profile-dev-test/10.md +++ b/src/courses/profile-dev-test/10.md @@ -1,7 +1,7 @@ --- order: 10 next: 11.md -title: What Is `Done` for a Control? +title: 10. What Is `Done` for a Control? author: Aaron Lippold --- @@ -33,14 +33,14 @@ Understanding when a security control is truly "done" is crucial for security au You and your team might be wondering what 'done' means for a security control in your profile. Here are a few things to consider: -1. The security automation content and its tests are essentially a refactoring of the 'validation' and 'remediation' guidance already established by the benchmark. +1. The security automation content and its tests are essentially an alternative definition of the 'validation' and 'remediation' guidance already established by the benchmark. 2. The security automation content tests should fully capture the spirit - or intention - of the guidance, including its caveats, notes, discussion, and 'validation' and 'remediation' content. -3. The tests can - and usually do - capture known 'corner cases and security best practices' that are sometimes indirectly or not directly addressed by the benchmark but implied by the spirit of the security requirement being addressed. +3. The tests can - and usually do - capture known corner cases and security best practices which are sometimes only indirectly addressed by the benchmark but implied by the spirit of the security requirement being addressed. 4. These tests, like all human-written code, may not be perfect. They will need updates and will evolve as our knowledge of the system and benchmark grows. We use the profile in production and real-world environments. In other words, don't let the pursuit of perfection hinder progress. The 'is it done' litmus test is not solely determined by a perfect InSpec control or describe and expect blocks. It also heavily relies on you, the security automation engineer. Your experience, understanding of the platform you're working on, and the processes that you and your team have collectively agreed upon are all vital components. -Trust your established expected test outcomes, the guidance document, and the CI/CD testing framework. They will help you know that, to the best of your ability, you have captured the spirit of the testing required by the Benchmark. +Trust your established expected test outcomes, the guidance document, and the CI/CD testing framework. They will help you know that, to the best of your ability, you have captured all requirements and the spirit of the testing specified by the benchmark. ## The MITRE SAF Testing Framework @@ -48,20 +48,19 @@ Our framework provides a comprehensive approach to testing controls. We call thi We consider a control effectively tested when: -1. All aspects of the 'validation' - also known as 'check text' - have been addressed. -2. Any aspects of the 'remediation' - also known as 'fix text' - that are part of the 'validation' process have been captured. +1. All aspects of the 'validation' - also known as 'check text' - have been addressed. This is usually straightforward. +2. Any aspects of the 'remediation' - also known as 'fix text' - that are part of the 'validation' process have been captured. Sometimes guidance authors mix the type of information between the 'check' and 'fix' text areas, so we need to comprehensively read all of the guidance to ensure that we've extracted all of the 'validation' content wherever it might be. 3. Any documented conditions that are Not Applicable, as outlined in the 'discussion', 'check', or 'fix' text, have been addressed. -4. Any documented conditions that have Not Been Reviewed, as outlined in the 'discussion', 'check', or 'fix' text, have been addressed. -5. The conditions for Not Applicable and Not Reviewed are early in the control to ensure the control is as efficient as possible. +4. Any documented conditions that require manual review, as outlined in the 'discussion', 'check', or 'fix' text, have been addressed such that the control is marked as Not Reviewed on execution of the profile. +5. The conditions for Not Applicable and Not Reviewed are assessed early in the control to ensure the control is as efficient as possible. 6. The control uses the `only_if` block vs 'if/else' logic when possible to ensure that the control is as clear, direct, and maintainable as possible from a coding perspective. 7. The control has been tested on both 'vanilla' and 'hardened' instances, ensuring that: - 1. The test communicates effectively and fails as expected on the 'vanilla' testing target. - 2. The test communicates effectively and passes on the 'hardened' testing target. - 3. The test communicates effectively and fails on a misconfigured 'vanilla' testing target. - 4. The test communicates effectively and fails on a misconfigured 'hardened' testing target. - 5. The test communicates effectively and clearly articulates the Not Applicable condition for both 'vanilla' and 'hardened' testing targets. - 6. The test communicates effectively and clearly articulates the Not Reviewed condition for both the 'vanilla' and 'hardened' testing targets. - 7. The tests have been constructed in a way that they do not produce Profile Errors when looping, using conditional logic, or when system conditions - such as missing files, directories, or services - are not in the expected locations. + 1. The test communicates effectively and passes as expected on both the 'vanilla' and `hardened` testing targets which were correctly configured. + 2. The test communicates effectively and fails as expected on both the `vanilla` and `hardened` testing targets which were misconfigured. + 3. The test communicates effectively and fails as expected on a misconfigured `vanilla` target, but then passes as expected on a properly configured `hardened` target. + 4. The test communicates effectively and clearly articulates the Not Applicable condition for both 'vanilla' and 'hardened' testing targets. + 5. The test communicates effectively and clearly articulates the Not Reviewed condition for both the 'vanilla' and 'hardened' testing targets. + 6. The tests have been constructed in a way that they do not produce Profile Errors when looping, using conditional logic, or when system conditions - such as missing files, directories, or services - are not in the expected locations. ## Best Practices for Test Implementation @@ -111,10 +110,142 @@ For example: Let's practice implementing a basic control: -1. Create a basic control test -2. Add passing and failing scenarios -3. Implement clear communication -4. Test edge cases +::: code-tabs#ruby + +@tab Create a basic control test +```ruby +control 'SV-257844' do + title 'RHEL 9 must use a separate file system for /tmp.' + desc 'The "/tmp" partition is used as temporary storage by many programs. Placing "/tmp" in its own partition enables the setting of more restrictive mount options, which can help protect programs that use it.' + desc 'check', 'Verify that a separate file system/partition has been created for "/tmp" with the following command: + +$ mount | grep /tmp + +tmpfs /tmp tmpfs noatime,mode=1777 0 0 + +If a separate entry for "/tmp" is not in use, this is a finding.' + desc 'fix', 'Migrate the "/tmp" path onto a separate file system.' + impact 0.5 + ref 'DPMS Target Red Hat Enterprise Linux 9' + tag severity: 'medium' + tag gtitle: 'SRG-OS-000480-GPOS-00227' + tag gid: 'V-257844' + tag rid: 'SV-257844r925519_rule' + tag stig_id: 'RHEL-09-231015' + tag fix_id: 'F-61509r925518_fix' + tag cci: ['CCI-000366'] + tag nist: ['CM-6 b'] + tag 'host' +end +``` +@tab Add passing and failing scenarios +```ruby +control 'SV-257844' do + title 'RHEL 9 must use a separate file system for /tmp.' + desc 'The "/tmp" partition is used as temporary storage by many programs. Placing "/tmp" in its own partition enables the setting of more restrictive mount options, which can help protect programs that use it.' + desc 'check', 'Verify that a separate file system/partition has been created for "/tmp" with the following command: + +$ mount | grep /tmp + +tmpfs /tmp tmpfs noatime,mode=1777 0 0 + +If a separate entry for "/tmp" is not in use, this is a finding.' + desc 'fix', 'Migrate the "/tmp" path onto a separate file system.' + impact 0.5 + ref 'DPMS Target Red Hat Enterprise Linux 9' + tag severity: 'medium' + tag gtitle: 'SRG-OS-000480-GPOS-00227' + tag gid: 'V-257844' + tag rid: 'SV-257844r925519_rule' + tag stig_id: 'RHEL-09-231015' + tag fix_id: 'F-61509r925518_fix' + tag cci: ['CCI-000366'] + tag nist: ['CM-6 b'] + tag 'host' + + tmp = mount('/tmp') + is_mounted = tmp.mounted? + describe is_mounted do + it { should cmp true } + end + + describe etc_fstab.where { mount_point == '/tmp' } do + it { should exist } + end +end +``` +@tab Implement clear communication +```ruby +control 'SV-257844' do + title 'RHEL 9 must use a separate file system for /tmp.' + desc 'The "/tmp" partition is used as temporary storage by many programs. Placing "/tmp" in its own partition enables the setting of more restrictive mount options, which can help protect programs that use it.' + desc 'check', 'Verify that a separate file system/partition has been created for "/tmp" with the following command: + +$ mount | grep /tmp + +tmpfs /tmp tmpfs noatime,mode=1777 0 0 + +If a separate entry for "/tmp" is not in use, this is a finding.' + desc 'fix', 'Migrate the "/tmp" path onto a separate file system.' + impact 0.5 + ref 'DPMS Target Red Hat Enterprise Linux 9' + tag severity: 'medium' + tag gtitle: 'SRG-OS-000480-GPOS-00227' + tag gid: 'V-257844' + tag rid: 'SV-257844r925519_rule' + tag stig_id: 'RHEL-09-231015' + tag fix_id: 'F-61509r925518_fix' + tag cci: ['CCI-000366'] + tag nist: ['CM-6 b'] + tag 'host' + + describe mount('/tmp') do + it { should be_mounted } + end + + describe etc_fstab.where { mount_point == '/tmp' } do + it { should exist } + end +end +``` +@tab Test edge cases +```ruby +control 'SV-257844' do + title 'RHEL 9 must use a separate file system for /tmp.' + desc 'The "/tmp" partition is used as temporary storage by many programs. Placing "/tmp" in its own partition enables the setting of more restrictive mount options, which can help protect programs that use it.' + desc 'check', 'Verify that a separate file system/partition has been created for "/tmp" with the following command: + +$ mount | grep /tmp + +tmpfs /tmp tmpfs noatime,mode=1777 0 0 + +If a separate entry for "/tmp" is not in use, this is a finding.' + desc 'fix', 'Migrate the "/tmp" path onto a separate file system.' + impact 0.5 + ref 'DPMS Target Red Hat Enterprise Linux 9' + tag severity: 'medium' + tag gtitle: 'SRG-OS-000480-GPOS-00227' + tag gid: 'V-257844' + tag rid: 'SV-257844r925519_rule' + tag stig_id: 'RHEL-09-231015' + tag fix_id: 'F-61509r925518_fix' + tag cci: ['CCI-000366'] + tag nist: ['CM-6 b'] + tag 'host' + + only_if('This control is Not Applicable to containers', impact: 0.0) { + !virtualization.system.eql?('docker') + } + + describe mount('/tmp') do + it { should be_mounted } + end + + describe etc_fstab.where { mount_point == '/tmp' } do + it { should exist } + end +end +``` ## Key Takeaways @@ -132,9 +263,9 @@ You might use a Spreadsheet or CSV file, a Markdown or RST Table, or even a 'che All these methods are acceptable. The important thing is to **choose one method and use it consistently.** -When working with multiple team members, it's crucial to have an effective way to communicate progress, understand who is working on which parts of the security guide, and know what 'still needs work' without constant direct communication. +When working with multiple team members, it's crucial to have an effective way to communicate progress, understand who is working on which parts of the security guide, and know what still needs work without constant direct communication. -The tracking method will also be influenced by the PR process you and your team select - either 'Macro' or 'Micro' - as discussed in the [Micro vs Macro](https://mitre.github.io/saf-training/courses/profile-dev-test/07.html#micro-vs-massive-pull-requests-prs) section. +The tracking method will also be influenced by the PR process you and your team select - either 'Macro' or 'Micro' - as discussed in the [Micro vs Macro](./07.md) section. ## Example Tracking Table @@ -162,10 +293,10 @@ The MITRE SAF team has found the following best practices effective for organizi 1. **Group Similar Controls:** When working on a security guidance document, group the controls you are working on using the guidance indexes - such as the SRG ID in STIGs, and requirement major version in CIS Benchmarks. This allows for efficient reuse of repeated patterns of control implementation. -2. **Tags, Status Columns & State:** As a team, decide on the method for tracking work progress and agree on the terminology for concepts such as 'reviewed', 'tested', and 'done'/'completed'. Refer to the [`Tracking Table`](#simple-tracking-table) example above to understand how both 'technical' and 'business' requirements are tracked and reported for each requirement in the profile. +2. **Tags, Status Columns, and State:** As a team, decide on the method for tracking work progress and agree on the terminology for concepts such as 'reviewed', 'tested', and 'done'/'completed'. Refer to the [`Tracking Table`](#simple-tracking-table) example above to understand how both 'technical' and 'business' requirements are tracked and reported for each requirement in the profile. -3. **Assign Priority & Agree on an In/Out Approach:** Every benchmark will have easy, medium, and complex requirements and tests that need implementation. You will need to review every control in the Profile, but choosing an 'easy first, hard last' or 'hard first, easy last' approach can help your team make efficient progress quickly and avoid continuous 'context switching' between straightforward and complicated testing. +3. **Assign Priority, and Agree on an In/Out Approach:** Every benchmark will have easy, medium, and complex requirements and tests that need implementation. You will need to review every control in the Profile, but choosing an 'easy first, hard last' or 'hard first, easy last' approach can help your team make efficient progress quickly and avoid continuous 'context switching' between straightforward and complicated testing. -4. **Always Strive to Have a Full Test Suite:** Ensuring the fidelity of testing is crucial. This principle applies to both the 'vanilla' and 'hardened' contexts, as well as to the 'primary deployment platforms' that your profile supports. These platforms might include Virtual Machines, Cloud Instances, and Container Deployments. Your goal should be to have both 'hardened' and 'vanilla' baselines for each deployment target. This strategy allows for easy provisioning of each platform. It also facilitates easy testing of your control on each platform as you progress from one control to another. This practice ensures that you are crafting the best possible tests for each target platform and configuration. +4. **Always Strive to Have a Full Test Suite:** Ensuring the fidelity of testing is crucial. This principle applies to both the 'vanilla' and 'hardened' contexts, as well as to the primary deployment platforms that your profile supports. These platforms might include Virtual Machines, Cloud Instances, and Container Deployments. Your goal should be to have both 'hardened' and 'vanilla' baselines for each deployment target. This strategy allows for easy provisioning of each platform. It also facilitates easy testing of your control on each platform as you progress from one control to another. This practice ensures that you are crafting the best possible tests for each target platform and configuration. 5. **Try to Test Locally First, with the Pipeline Second:** One of the key patterns highlighted in this guidance is the combination of local and CI/CD-based testing. We advocate for both approaches for a specific reason. When you are working on multiple controls, it's more efficient to test each control on each platform locally. This method is quicker than waiting for the CI/CD pipeline to create a new deployment of the test and target platforms each time. Once you have configured your targets and platforms locally with Test Kitchen, you can be confident in their stability. You should prioritize these local targets for initial testing. After testing them and when you are ready to proceed to the next control, push those updates to the CI/CD pipeline. This step verifies that your controls still function in a clean environment. This approach promotes a more efficient workflow process and eliminates the need for continuous 'push and wait' for the pipeline. From 7d9e6a828cd33b2c21b237456d75b15b387a079d Mon Sep 17 00:00:00 2001 From: Amndeep Singh Mann Date: Wed, 11 Dec 2024 13:13:37 -0800 Subject: [PATCH 15/27] forgot to close the code tabs Signed-off-by: Amndeep Singh Mann --- src/courses/profile-dev-test/10.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/courses/profile-dev-test/10.md b/src/courses/profile-dev-test/10.md index 8ee0f2464..7246aa210 100644 --- a/src/courses/profile-dev-test/10.md +++ b/src/courses/profile-dev-test/10.md @@ -246,6 +246,7 @@ If a separate entry for "/tmp" is not in use, this is a finding.' end end ``` +::: ## Key Takeaways From 769ee071003f98cc4495cfaaeb025cfee2297b27 Mon Sep 17 00:00:00 2001 From: Amndeep Singh Mann Date: Wed, 11 Dec 2024 13:33:57 -0800 Subject: [PATCH 16/27] slight reordering so that it's profile management, then profile updates, and then what is each kind of update Signed-off-by: Amndeep Singh Mann --- src/courses/profile-dev-test/09.md | 349 ++++++++++++++++++++++++----- src/courses/profile-dev-test/10.md | 314 +++----------------------- src/courses/profile-dev-test/11.md | 119 +++++----- 3 files changed, 391 insertions(+), 391 deletions(-) diff --git a/src/courses/profile-dev-test/09.md b/src/courses/profile-dev-test/09.md index 9e046c754..9cb8b3163 100644 --- a/src/courses/profile-dev-test/09.md +++ b/src/courses/profile-dev-test/09.md @@ -1,72 +1,303 @@ --- order: 9 next: 10.md -title: 9. Understanding Profile Updates +title: 9. What Is `Done` for a Control? author: Aaron Lippold --- +# Understanding Control Completion in Security Automation + ## Learning Objectives By the end of this section, you will be able to: -- Identify the three types of profile updates -- Understand the scope of STIG and CIS Benchmark updates -- Recognize the forward-only nature of security benchmark updates - -## Types of Profile Updates - -Security benchmark profiles require regular updates to maintain their effectiveness. Let's explore the three main types of updates: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Patch UpdatesRelease UpdatesMajor Version Updates
ScopeMinorIntermediateIntermediate/Significant
TriggerThe validation code author desiring to address corner cases, fix bugs, or otherwise improve the quality of the tests.Guidance author making a new release of the benchmark to address new or updated security requirements.The guidance author is significantly overhauling their nomenclature, requirement identification schema, or control alignment. Alternatively, a new major version of the software system is being released which would require a new version of the benchmark to address the potentially significant implementation changes - though in this case, guidance authors sometimes choose to create a new benchmark entirely.
ExampleAn InSpec control did not properly address a caveat specified by the guidance. Making the fix bumps the profile from v1.3.4 to v1.3.5.DISA publishes a new version of the RHEL 8 STIG going from V1R13 to V1R14 in order to adjust the check text command syntax for several sshd configuration related requirements amongst other things. Making the changes bumps the profile from v1.13.4 to v1.14.0.DISA adds, removes, and modifies a substantial number of requirements due to transitioning between control versions (NIST SP 800-53 Rev. 4 to Rev. 5). Making the changes bumps the profile from v1.6.1 to v2.0.0.
- -## Understanding Update Scope - -Important concepts to remember: - -- Updates are version-specific -- Changes only move forward ("forward-only" process) -- No "back-patching" to older versions -- Each requirement maps to: - - Source SRG document - - Control Correlation Identifier (CCI) - - Unique Rule and STIG IDs - -Example requirement identifiers: +- Define the criteria for a "done" security control +- Apply the MITRE SAF yardstick to evaluate controls +- Implement effective control testing strategies +- Create and maintain progress tracking systems +- Debug common control implementation issues + +## Knowledge Check Questions + +Before we begin, consider these questions: + +1. What makes a security control "complete"? +2. How do you verify a control works in different environments? +3. What's the difference between "passing well" and just passing? + +## Introduction + +Understanding when a security control is truly "done" is crucial for security automation engineers. This section will guide you through the criteria, best practices, and practical approaches to ensure your controls are complete and effective. + +## When is a Control Considered 'Done' + +You and your team might be wondering what 'done' means for a security control in your profile. Here are a few things to consider: + +1. The security automation content and its tests are essentially an alternative definition of the 'validation' and 'remediation' guidance already established by the benchmark. +2. The security automation content tests should fully capture the spirit - or intention - of the guidance, including its caveats, notes, discussion, and 'validation' and 'remediation' content. +3. The tests can - and usually do - capture known corner cases and security best practices which are sometimes only indirectly addressed by the benchmark but implied by the spirit of the security requirement being addressed. +4. These tests, like all human-written code, may not be perfect. They will need updates and will evolve as our knowledge of the system and benchmark grows. We use the profile in production and real-world environments. In other words, don't let the pursuit of perfection hinder progress. + +The 'is it done' litmus test is not solely determined by a perfect InSpec control or describe and expect blocks. It also heavily relies on you, the security automation engineer. Your experience, understanding of the platform you're working on, and the processes that you and your team have collectively agreed upon are all vital components. + +Trust your established expected test outcomes, the guidance document, and the CI/CD testing framework. They will help you know that, to the best of your ability, you have captured all requirements and the spirit of the testing specified by the benchmark. + +## The MITRE SAF Testing Framework + +Our framework provides a comprehensive approach to testing controls. We call this the "SAF Yardstick": + +We consider a control effectively tested when: + +1. All aspects of the 'validation' - also known as 'check text' - have been addressed. This is usually straightforward. +2. Any aspects of the 'remediation' - also known as 'fix text' - that are part of the 'validation' process have been captured. Sometimes guidance authors mix the type of information between the 'check' and 'fix' text areas, so we need to comprehensively read all of the guidance to ensure that we've extracted all of the 'validation' content wherever it might be. +3. Any documented conditions that are Not Applicable, as outlined in the 'discussion', 'check', or 'fix' text, have been addressed. +4. Any documented conditions that require manual review, as outlined in the 'discussion', 'check', or 'fix' text, have been addressed such that the control is marked as Not Reviewed on execution of the profile. +5. The conditions for Not Applicable and Not Reviewed are assessed early in the control to ensure the control is as efficient as possible. +6. The control uses the `only_if` block vs 'if/else' logic when possible to ensure that the control is as clear, direct, and maintainable as possible from a coding perspective. +7. The control has been tested on both 'vanilla' and 'hardened' instances, ensuring that: + 1. The test communicates effectively and passes as expected on both the 'vanilla' and `hardened` testing targets which were correctly configured. + 2. The test communicates effectively and fails as expected on both the `vanilla` and `hardened` testing targets which were misconfigured. + 3. The test communicates effectively and fails as expected on a misconfigured `vanilla` target, but then passes as expected on a properly configured `hardened` target. + 4. The test communicates effectively and clearly articulates the Not Applicable condition for both 'vanilla' and 'hardened' testing targets. + 5. The test communicates effectively and clearly articulates the Not Reviewed condition for both the 'vanilla' and 'hardened' testing targets. + 6. The tests have been constructed in a way that they do not produce Profile Errors when looping, using conditional logic, or when system conditions - such as missing files, directories, or services - are not in the expected locations. + +## Best Practices for Test Implementation + +### Passing Tests (Passing Well) + +A well-implemented passing test should: + +- Clearly communicate success conditions +- Use simple, direct language +- Include validation of edge cases + +For example: + +```shell +✔ SV-230222: RHEL 8 vendor packaged system security patches and updates must be installed and up to date. + ✔ All system security patches and updates are up to date and have been applied +``` + +`Passes as Expected` also encompasses: + +- The conditions for the Not Reviewed and Not Applicable states for the control, if any. + +### Failing Tests (Failing Well) + +When implementing failure scenarios, ensure: + +- Clear error messages +- Actionable feedback +- Proper error handling + +For example: + +```shell +✔ SV-230222: RHEL 8 vendor packaged system security patches and updates must be installed and up to date. + x The following packages have security patches and need to be updated: + - package 1 + - package 2 + - package 3 + - package 4 +``` + +`Fails as Expected` also encompasses: + +- Misconfigurations, extra lines in files, extra settings, missing files, etc. + +## Hands-on Exercise 1: Creating Your First Control + +Let's practice implementing a basic control: + +::: code-tabs#ruby + +@tab Create a basic control test +```ruby +control 'SV-257844' do + title 'RHEL 9 must use a separate file system for /tmp.' + desc 'The "/tmp" partition is used as temporary storage by many programs. Placing "/tmp" in its own partition enables the setting of more restrictive mount options, which can help protect programs that use it.' + desc 'check', 'Verify that a separate file system/partition has been created for "/tmp" with the following command: + +$ mount | grep /tmp + +tmpfs /tmp tmpfs noatime,mode=1777 0 0 + +If a separate entry for "/tmp" is not in use, this is a finding.' + desc 'fix', 'Migrate the "/tmp" path onto a separate file system.' + impact 0.5 + ref 'DPMS Target Red Hat Enterprise Linux 9' + tag severity: 'medium' + tag gtitle: 'SRG-OS-000480-GPOS-00227' + tag gid: 'V-257844' + tag rid: 'SV-257844r925519_rule' + tag stig_id: 'RHEL-09-231015' + tag fix_id: 'F-61509r925518_fix' + tag cci: ['CCI-000366'] + tag nist: ['CM-6 b'] + tag 'host' +end +``` +@tab Add passing and failing scenarios +```ruby +control 'SV-257844' do + title 'RHEL 9 must use a separate file system for /tmp.' + desc 'The "/tmp" partition is used as temporary storage by many programs. Placing "/tmp" in its own partition enables the setting of more restrictive mount options, which can help protect programs that use it.' + desc 'check', 'Verify that a separate file system/partition has been created for "/tmp" with the following command: + +$ mount | grep /tmp + +tmpfs /tmp tmpfs noatime,mode=1777 0 0 +If a separate entry for "/tmp" is not in use, this is a finding.' + desc 'fix', 'Migrate the "/tmp" path onto a separate file system.' + impact 0.5 + ref 'DPMS Target Red Hat Enterprise Linux 9' + tag severity: 'medium' + tag gtitle: 'SRG-OS-000480-GPOS-00227' + tag gid: 'V-257844' + tag rid: 'SV-257844r925519_rule' + tag stig_id: 'RHEL-09-231015' + tag fix_id: 'F-61509r925518_fix' + tag cci: ['CCI-000366'] + tag nist: ['CM-6 b'] + tag 'host' + + tmp = mount('/tmp') + is_mounted = tmp.mounted? + describe is_mounted do + it { should cmp true } + end + + describe etc_fstab.where { mount_point == '/tmp' } do + it { should exist } + end +end +``` +@tab Implement clear communication ```ruby -tag gtitle: 'SRG-OS-000480-GPOS-00227' -tag gid: 'V-230221' -tag rid: 'SV-230221r858734_rule' -tag stig_id: 'RHEL-08-010000' -tag fix_id: 'F-32865r567410_fix' -tag cci: ['CCI-000366'] +control 'SV-257844' do + title 'RHEL 9 must use a separate file system for /tmp.' + desc 'The "/tmp" partition is used as temporary storage by many programs. Placing "/tmp" in its own partition enables the setting of more restrictive mount options, which can help protect programs that use it.' + desc 'check', 'Verify that a separate file system/partition has been created for "/tmp" with the following command: + +$ mount | grep /tmp + +tmpfs /tmp tmpfs noatime,mode=1777 0 0 + +If a separate entry for "/tmp" is not in use, this is a finding.' + desc 'fix', 'Migrate the "/tmp" path onto a separate file system.' + impact 0.5 + ref 'DPMS Target Red Hat Enterprise Linux 9' + tag severity: 'medium' + tag gtitle: 'SRG-OS-000480-GPOS-00227' + tag gid: 'V-257844' + tag rid: 'SV-257844r925519_rule' + tag stig_id: 'RHEL-09-231015' + tag fix_id: 'F-61509r925518_fix' + tag cci: ['CCI-000366'] + tag nist: ['CM-6 b'] + tag 'host' + + describe mount('/tmp') do + it { should be_mounted } + end + + describe etc_fstab.where { mount_point == '/tmp' } do + it { should exist } + end +end ``` +@tab Test edge cases +```ruby +control 'SV-257844' do + title 'RHEL 9 must use a separate file system for /tmp.' + desc 'The "/tmp" partition is used as temporary storage by many programs. Placing "/tmp" in its own partition enables the setting of more restrictive mount options, which can help protect programs that use it.' + desc 'check', 'Verify that a separate file system/partition has been created for "/tmp" with the following command: + +$ mount | grep /tmp + +tmpfs /tmp tmpfs noatime,mode=1777 0 0 + +If a separate entry for "/tmp" is not in use, this is a finding.' + desc 'fix', 'Migrate the "/tmp" path onto a separate file system.' + impact 0.5 + ref 'DPMS Target Red Hat Enterprise Linux 9' + tag severity: 'medium' + tag gtitle: 'SRG-OS-000480-GPOS-00227' + tag gid: 'V-257844' + tag rid: 'SV-257844r925519_rule' + tag stig_id: 'RHEL-09-231015' + tag fix_id: 'F-61509r925518_fix' + tag cci: ['CCI-000366'] + tag nist: ['CM-6 b'] + tag 'host' + + only_if('This control is Not Applicable to containers', impact: 0.0) { + !virtualization.system.eql?('docker') + } + + describe mount('/tmp') do + it { should be_mounted } + end + + describe etc_fstab.where { mount_point == '/tmp' } do + it { should exist } + end +end +``` +::: + +## Key Takeaways + +- Control completion is more than just passing tests +- Use the SAF Yardstick as your guide +- Clear communication is essential +- Track progress consistently +- Group similar controls for efficiency + +## Tracking Your Progress + +Updating a 'Patch', 'Release', or 'Major Version' can be a challenging task. However, there are several methods a team can use to track progress. + +You might use a Spreadsheet or CSV file, a Markdown or RST Table, or even a 'checklist' on the 'Pull Request' that your team updates as progress is made. + +All these methods are acceptable. The important thing is to **choose one method and use it consistently.** + +When working with multiple team members, it's crucial to have an effective way to communicate progress, understand who is working on which parts of the security guide, and know what still needs work without constant direct communication. + +The tracking method will also be influenced by the PR process you and your team select - either 'Macro' or 'Micro' - as discussed in the [Micro vs Macro](./07.md) section. + +## Example Tracking Table + +The key to effective tracking is simplicity. This ensures: + +1) Each team member can easily understand what and how they need to document their progress, and +2) They will actually document their progress. + +### Simple Tracking Table + +| Assignee | Control | Priority | Reviewed | Tested | Text Updated | New Resource | Inputs | +| -------- | --------- | -------- | -------- | ------ | ------------ | ------------ | ----------------------- | +| John | SV-230221 | N | Y | Y | Y | N | None | +| John | SV-230222 | Y | Y | Y | Y | N | `disable_slow_controls` | +| Jane | SV-230223 | Y | Y | Y | Y | N | `use_fips` | +| Bob | SV-230224 | Y | Y | Y | Y | N | `data_at_rest_exempt` | + +In this example, we used a simple markdown table. However, an Excel Spreadsheet, Google Sheet, or CSV might work better for your team. + +Ultimately, the most important thing is to track the work. The method you choose to do so is a team decision. + +## Considerations for Grouping Work + +The MITRE SAF team has found the following best practices effective for organizing our work: + +1. **Group Similar Controls:** When working on a security guidance document, group the controls you are working on using the guidance indexes - such as the SRG ID in STIGs, and requirement major version in CIS Benchmarks. This allows for efficient reuse of repeated patterns of control implementation. + +2. **Tags, Status Columns, and State:** As a team, decide on the method for tracking work progress and agree on the terminology for concepts such as 'reviewed', 'tested', and 'done'/'completed'. Refer to the [`Tracking Table`](#simple-tracking-table) example above to understand how both 'technical' and 'business' requirements are tracked and reported for each requirement in the profile. + +3. **Assign Priority, and Agree on an In/Out Approach:** Every benchmark will have easy, medium, and complex requirements and tests that need implementation. You will need to review every control in the Profile, but choosing an 'easy first, hard last' or 'hard first, easy last' approach can help your team make efficient progress quickly and avoid continuous 'context switching' between straightforward and complicated testing. + +4. **Always Strive to Have a Full Test Suite:** Ensuring the fidelity of testing is crucial. This principle applies to both the 'vanilla' and 'hardened' contexts, as well as to the primary deployment platforms that your profile supports. These platforms might include Virtual Machines, Cloud Instances, and Container Deployments. Your goal should be to have both 'hardened' and 'vanilla' baselines for each deployment target. This strategy allows for easy provisioning of each platform. It also facilitates easy testing of your control on each platform as you progress from one control to another. This practice ensures that you are crafting the best possible tests for each target platform and configuration. + +5. **Try to Test Locally First, with the Pipeline Second:** One of the key patterns highlighted in this guidance is the combination of local and CI/CD-based testing. We advocate for both approaches for a specific reason. When you are working on multiple controls, it's more efficient to test each control on each platform locally. This method is quicker than waiting for the CI/CD pipeline to create a new deployment of the test and target platforms each time. Once you have configured your targets and platforms locally with Test Kitchen, you can be confident in their stability. You should prioritize these local targets for initial testing. After testing them and when you are ready to proceed to the next control, push those updates to the CI/CD pipeline. This step verifies that your controls still function in a clean environment. This approach promotes a more efficient workflow process and eliminates the need for continuous 'push and wait' for the pipeline. diff --git a/src/courses/profile-dev-test/10.md b/src/courses/profile-dev-test/10.md index 7246aa210..0f48dc35f 100644 --- a/src/courses/profile-dev-test/10.md +++ b/src/courses/profile-dev-test/10.md @@ -1,303 +1,59 @@ --- order: 10 next: 11.md -title: 10. What Is `Done` for a Control? +title: 10. Security Benchmark Profile Management author: Aaron Lippold --- -# Understanding Control Completion in Security Automation +## Introduction to Profile Management -## Learning Objectives +Security benchmark profiles are critical tools for maintaining system security standards. Before diving into the implementation details, let's understand the fundamental principles that guide their management. -By the end of this section, you will be able to: +## Core Principles of Profile Management -- Define the criteria for a "done" security control -- Apply the MITRE SAF yardstick to evaluate controls -- Implement effective control testing strategies -- Create and maintain progress tracking systems -- Debug common control implementation issues +### 1. Version Control and Integrity -## Knowledge Check Questions +**Key Rule: Keep Versions Separate** -Before we begin, consider these questions: +- Never mix requirements from different versions +- Each version represents a distinct security baseline +- Example: Don't combine STIG v2.5 requirements with v3.0 requirements -1. What makes a security control "complete"? -2. How do you verify a control works in different environments? -3. What's the difference between "passing well" and just passing? +### 2. Completeness Principle -## Introduction +**Key Rule: All or Nothing** -Understanding when a security control is truly "done" is crucial for security automation engineers. This section will guide you through the criteria, best practices, and practical approaches to ensure your controls are complete and effective. +- Security benchmarks must include all requirements for a specific version +- Think of it like a recipe - missing ingredients affect the final result +- Focus on one requirement at a time during development +- Example: A Windows 10 STIG profile must implement all controls specified in that version -## When is a Control Considered 'Done' +### 3. Release Management -You and your team might be wondering what 'done' means for a security control in your profile. Here are a few things to consider: +**Key Rule: Meet All Standards** -1. The security automation content and its tests are essentially an alternative definition of the 'validation' and 'remediation' guidance already established by the benchmark. -2. The security automation content tests should fully capture the spirit - or intention - of the guidance, including its caveats, notes, discussion, and 'validation' and 'remediation' content. -3. The tests can - and usually do - capture known corner cases and security best practices which are sometimes only indirectly addressed by the benchmark but implied by the spirit of the security requirement being addressed. -4. These tests, like all human-written code, may not be perfect. They will need updates and will evolve as our knowledge of the system and benchmark grows. We use the profile in production and real-world environments. In other words, don't let the pursuit of perfection hinder progress. +- Release readiness is determined by: + - Passing all validation tests + - Meeting security hardening requirements + - Achieving expected thresholds -The 'is it done' litmus test is not solely determined by a perfect InSpec control or describe and expect blocks. It also heavily relies on you, the security automation engineer. Your experience, understanding of the platform you're working on, and the processes that you and your team have collectively agreed upon are all vital components. +### 4. Testing Environment Standards -Trust your established expected test outcomes, the guidance document, and the CI/CD testing framework. They will help you know that, to the best of your ability, you have captured all requirements and the spirit of the testing specified by the benchmark. +**Key Rule: Use Standard Baselines** -## The MITRE SAF Testing Framework +- Start with vendor-managed standard releases +- Test against both: + - Default ("vanilla") configurations + - Hardened configurations +- This ensures real-world applicability -Our framework provides a comprehensive approach to testing controls. We call this the "SAF Yardstick": +## Best Practices for Implementation -We consider a control effectively tested when: +1. Document your testing environment +2. Maintain a changelog for each profile version +3. Use version control for tracking changes +4. Test thoroughly before releasing -1. All aspects of the 'validation' - also known as 'check text' - have been addressed. This is usually straightforward. -2. Any aspects of the 'remediation' - also known as 'fix text' - that are part of the 'validation' process have been captured. Sometimes guidance authors mix the type of information between the 'check' and 'fix' text areas, so we need to comprehensively read all of the guidance to ensure that we've extracted all of the 'validation' content wherever it might be. -3. Any documented conditions that are Not Applicable, as outlined in the 'discussion', 'check', or 'fix' text, have been addressed. -4. Any documented conditions that require manual review, as outlined in the 'discussion', 'check', or 'fix' text, have been addressed such that the control is marked as Not Reviewed on execution of the profile. -5. The conditions for Not Applicable and Not Reviewed are assessed early in the control to ensure the control is as efficient as possible. -6. The control uses the `only_if` block vs 'if/else' logic when possible to ensure that the control is as clear, direct, and maintainable as possible from a coding perspective. -7. The control has been tested on both 'vanilla' and 'hardened' instances, ensuring that: - 1. The test communicates effectively and passes as expected on both the 'vanilla' and `hardened` testing targets which were correctly configured. - 2. The test communicates effectively and fails as expected on both the `vanilla` and `hardened` testing targets which were misconfigured. - 3. The test communicates effectively and fails as expected on a misconfigured `vanilla` target, but then passes as expected on a properly configured `hardened` target. - 4. The test communicates effectively and clearly articulates the Not Applicable condition for both 'vanilla' and 'hardened' testing targets. - 5. The test communicates effectively and clearly articulates the Not Reviewed condition for both the 'vanilla' and 'hardened' testing targets. - 6. The tests have been constructed in a way that they do not produce Profile Errors when looping, using conditional logic, or when system conditions - such as missing files, directories, or services - are not in the expected locations. +## Summary -## Best Practices for Test Implementation - -### Passing Tests (Passing Well) - -A well-implemented passing test should: - -- Clearly communicate success conditions -- Use simple, direct language -- Include validation of edge cases - -For example: - -```shell -✔ SV-230222: RHEL 8 vendor packaged system security patches and updates must be installed and up to date. - ✔ All system security patches and updates are up to date and have been applied -``` - -`Passes as Expected` also encompasses: - -- The conditions for the Not Reviewed and Not Applicable states for the control, if any. - -### Failing Tests (Failing Well) - -When implementing failure scenarios, ensure: - -- Clear error messages -- Actionable feedback -- Proper error handling - -For example: - -```shell -✔ SV-230222: RHEL 8 vendor packaged system security patches and updates must be installed and up to date. - x The following packages have security patches and need to be updated: - - package 1 - - package 2 - - package 3 - - package 4 -``` - -`Fails as Expected` also encompasses: - -- Misconfigurations, extra lines in files, extra settings, missing files, etc. - -## Hands-on Exercise 1: Creating Your First Control - -Let's practice implementing a basic control: - -::: code-tabs#ruby - -@tab Create a basic control test -```ruby -control 'SV-257844' do - title 'RHEL 9 must use a separate file system for /tmp.' - desc 'The "/tmp" partition is used as temporary storage by many programs. Placing "/tmp" in its own partition enables the setting of more restrictive mount options, which can help protect programs that use it.' - desc 'check', 'Verify that a separate file system/partition has been created for "/tmp" with the following command: - -$ mount | grep /tmp - -tmpfs /tmp tmpfs noatime,mode=1777 0 0 - -If a separate entry for "/tmp" is not in use, this is a finding.' - desc 'fix', 'Migrate the "/tmp" path onto a separate file system.' - impact 0.5 - ref 'DPMS Target Red Hat Enterprise Linux 9' - tag severity: 'medium' - tag gtitle: 'SRG-OS-000480-GPOS-00227' - tag gid: 'V-257844' - tag rid: 'SV-257844r925519_rule' - tag stig_id: 'RHEL-09-231015' - tag fix_id: 'F-61509r925518_fix' - tag cci: ['CCI-000366'] - tag nist: ['CM-6 b'] - tag 'host' -end -``` -@tab Add passing and failing scenarios -```ruby -control 'SV-257844' do - title 'RHEL 9 must use a separate file system for /tmp.' - desc 'The "/tmp" partition is used as temporary storage by many programs. Placing "/tmp" in its own partition enables the setting of more restrictive mount options, which can help protect programs that use it.' - desc 'check', 'Verify that a separate file system/partition has been created for "/tmp" with the following command: - -$ mount | grep /tmp - -tmpfs /tmp tmpfs noatime,mode=1777 0 0 - -If a separate entry for "/tmp" is not in use, this is a finding.' - desc 'fix', 'Migrate the "/tmp" path onto a separate file system.' - impact 0.5 - ref 'DPMS Target Red Hat Enterprise Linux 9' - tag severity: 'medium' - tag gtitle: 'SRG-OS-000480-GPOS-00227' - tag gid: 'V-257844' - tag rid: 'SV-257844r925519_rule' - tag stig_id: 'RHEL-09-231015' - tag fix_id: 'F-61509r925518_fix' - tag cci: ['CCI-000366'] - tag nist: ['CM-6 b'] - tag 'host' - - tmp = mount('/tmp') - is_mounted = tmp.mounted? - describe is_mounted do - it { should cmp true } - end - - describe etc_fstab.where { mount_point == '/tmp' } do - it { should exist } - end -end -``` -@tab Implement clear communication -```ruby -control 'SV-257844' do - title 'RHEL 9 must use a separate file system for /tmp.' - desc 'The "/tmp" partition is used as temporary storage by many programs. Placing "/tmp" in its own partition enables the setting of more restrictive mount options, which can help protect programs that use it.' - desc 'check', 'Verify that a separate file system/partition has been created for "/tmp" with the following command: - -$ mount | grep /tmp - -tmpfs /tmp tmpfs noatime,mode=1777 0 0 - -If a separate entry for "/tmp" is not in use, this is a finding.' - desc 'fix', 'Migrate the "/tmp" path onto a separate file system.' - impact 0.5 - ref 'DPMS Target Red Hat Enterprise Linux 9' - tag severity: 'medium' - tag gtitle: 'SRG-OS-000480-GPOS-00227' - tag gid: 'V-257844' - tag rid: 'SV-257844r925519_rule' - tag stig_id: 'RHEL-09-231015' - tag fix_id: 'F-61509r925518_fix' - tag cci: ['CCI-000366'] - tag nist: ['CM-6 b'] - tag 'host' - - describe mount('/tmp') do - it { should be_mounted } - end - - describe etc_fstab.where { mount_point == '/tmp' } do - it { should exist } - end -end -``` -@tab Test edge cases -```ruby -control 'SV-257844' do - title 'RHEL 9 must use a separate file system for /tmp.' - desc 'The "/tmp" partition is used as temporary storage by many programs. Placing "/tmp" in its own partition enables the setting of more restrictive mount options, which can help protect programs that use it.' - desc 'check', 'Verify that a separate file system/partition has been created for "/tmp" with the following command: - -$ mount | grep /tmp - -tmpfs /tmp tmpfs noatime,mode=1777 0 0 - -If a separate entry for "/tmp" is not in use, this is a finding.' - desc 'fix', 'Migrate the "/tmp" path onto a separate file system.' - impact 0.5 - ref 'DPMS Target Red Hat Enterprise Linux 9' - tag severity: 'medium' - tag gtitle: 'SRG-OS-000480-GPOS-00227' - tag gid: 'V-257844' - tag rid: 'SV-257844r925519_rule' - tag stig_id: 'RHEL-09-231015' - tag fix_id: 'F-61509r925518_fix' - tag cci: ['CCI-000366'] - tag nist: ['CM-6 b'] - tag 'host' - - only_if('This control is Not Applicable to containers', impact: 0.0) { - !virtualization.system.eql?('docker') - } - - describe mount('/tmp') do - it { should be_mounted } - end - - describe etc_fstab.where { mount_point == '/tmp' } do - it { should exist } - end -end -``` -::: - -## Key Takeaways - -- Control completion is more than just passing tests -- Use the SAF Yardstick as your guide -- Clear communication is essential -- Track progress consistently -- Group similar controls for efficiency - -## Tracking Your Progress - -Updating a 'Patch', 'Release', or 'Major Version' can be a challenging task. However, there are several methods a team can use to track progress. - -You might use a Spreadsheet or CSV file, a Markdown or RST Table, or even a 'checklist' on the 'Pull Request' that your team updates as progress is made. - -All these methods are acceptable. The important thing is to **choose one method and use it consistently.** - -When working with multiple team members, it's crucial to have an effective way to communicate progress, understand who is working on which parts of the security guide, and know what still needs work without constant direct communication. - -The tracking method will also be influenced by the PR process you and your team select - either 'Macro' or 'Micro' - as discussed in the [Micro vs Macro](./07.md) section. - -## Example Tracking Table - -The key to effective tracking is simplicity. This ensures: - -1) Each team member can easily understand what and how they need to document their progress, and -2) They will actually document their progress. - -### Simple Tracking Table - -| Assignee | Control | Priority | Reviewed | Tested | Text Updated | New Resource | Inputs | -| -------- | --------- | -------- | -------- | ------ | ------------ | ------------ | ----------------------- | -| John | SV-230221 | N | Y | Y | Y | N | None | -| John | SV-230222 | Y | Y | Y | Y | N | `disable_slow_controls` | -| Jane | SV-230223 | Y | Y | Y | Y | N | `use_fips` | -| Bob | SV-230224 | Y | Y | Y | Y | N | `data_at_rest_exempt` | - -In this example, we used a simple markdown table. However, an Excel Spreadsheet, Google Sheet, or CSV might work better for your team. - -Ultimately, the most important thing is to track the work. The method you choose to do so is a team decision. - -## Considerations for Grouping Work - -The MITRE SAF team has found the following best practices effective for organizing our work: - -1. **Group Similar Controls:** When working on a security guidance document, group the controls you are working on using the guidance indexes - such as the SRG ID in STIGs, and requirement major version in CIS Benchmarks. This allows for efficient reuse of repeated patterns of control implementation. - -2. **Tags, Status Columns, and State:** As a team, decide on the method for tracking work progress and agree on the terminology for concepts such as 'reviewed', 'tested', and 'done'/'completed'. Refer to the [`Tracking Table`](#simple-tracking-table) example above to understand how both 'technical' and 'business' requirements are tracked and reported for each requirement in the profile. - -3. **Assign Priority, and Agree on an In/Out Approach:** Every benchmark will have easy, medium, and complex requirements and tests that need implementation. You will need to review every control in the Profile, but choosing an 'easy first, hard last' or 'hard first, easy last' approach can help your team make efficient progress quickly and avoid continuous 'context switching' between straightforward and complicated testing. - -4. **Always Strive to Have a Full Test Suite:** Ensuring the fidelity of testing is crucial. This principle applies to both the 'vanilla' and 'hardened' contexts, as well as to the primary deployment platforms that your profile supports. These platforms might include Virtual Machines, Cloud Instances, and Container Deployments. Your goal should be to have both 'hardened' and 'vanilla' baselines for each deployment target. This strategy allows for easy provisioning of each platform. It also facilitates easy testing of your control on each platform as you progress from one control to another. This practice ensures that you are crafting the best possible tests for each target platform and configuration. - -5. **Try to Test Locally First, with the Pipeline Second:** One of the key patterns highlighted in this guidance is the combination of local and CI/CD-based testing. We advocate for both approaches for a specific reason. When you are working on multiple controls, it's more efficient to test each control on each platform locally. This method is quicker than waiting for the CI/CD pipeline to create a new deployment of the test and target platforms each time. Once you have configured your targets and platforms locally with Test Kitchen, you can be confident in their stability. You should prioritize these local targets for initial testing. After testing them and when you are ready to proceed to the next control, push those updates to the CI/CD pipeline. This step verifies that your controls still function in a clean environment. This approach promotes a more efficient workflow process and eliminates the need for continuous 'push and wait' for the pipeline. +Remember: Security benchmarks are complete sets of requirements tied to specific versions. Success comes from methodical implementation and thorough testing against standard baselines. diff --git a/src/courses/profile-dev-test/11.md b/src/courses/profile-dev-test/11.md index b94741697..6928b0a96 100644 --- a/src/courses/profile-dev-test/11.md +++ b/src/courses/profile-dev-test/11.md @@ -1,59 +1,72 @@ --- order: 11 next: 12.md -title: Security Benchmark Profile Management +title: 11. Understanding Profile Updates author: Aaron Lippold --- -## Introduction to Profile Management - -Security benchmark profiles are critical tools for maintaining system security standards. Before diving into the implementation details, let's understand the fundamental principles that guide their management. - -## Core Principles of Profile Management - -### 1. Version Control and Integrity - -**Key Rule: Keep Versions Separate** - -- Never mix requirements from different versions -- Each version represents a distinct security baseline -- Example: Don't combine STIG v2.5 requirements with v3.0 requirements - -### 2. Completeness Principle - -**Key Rule: All or Nothing** - -- Security benchmarks must include all requirements for a specific version -- Think of it like a recipe - missing ingredients affect the final result -- Example: A Windows 10 STIG profile must implement all controls specified in that version - -### 3. Release Management - -**Key Rule: Meet All Standards** - -- Release readiness is determined by: - - Passing all validation tests - - Meeting security hardening requirements - - Achieving expected thresholds -- Focus on one requirement at a time during development - -### 4. Testing Environment Standards - -**Key Rule: Use Standard Baselines** - -- Start with vendor-managed standard releases -- Test against both: - - Default ("vanilla") configurations - - Hardened configurations -- This ensures real-world applicability - -## Best Practices for Implementation - -1. Document your testing environment -2. Maintain a changelog for each profile version -3. Use version control for tracking changes -4. Test thoroughly before releasing - -## Summary - -Remember: Security benchmarks are complete sets of requirements tied to specific versions. Success comes from methodical implementation and thorough testing against standard baselines. +## Learning Objectives + +By the end of this section, you will be able to: + +- Identify the three types of profile updates +- Understand the scope of STIG and CIS Benchmark updates +- Recognize the forward-only nature of security benchmark updates + +## Types of Profile Updates + +Security benchmark profiles require regular updates to maintain their effectiveness. Let's explore the three main types of updates: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Patch UpdatesRelease UpdatesMajor Version Updates
ScopeMinorIntermediateIntermediate/Significant
TriggerThe validation code author desiring to address corner cases, fix bugs, or otherwise improve the quality of the tests.Guidance author making a new release of the benchmark to address new or updated security requirements.The guidance author is significantly overhauling their nomenclature, requirement identification schema, or control alignment. Alternatively, a new major version of the software system is being released which would require a new version of the benchmark to address the potentially significant implementation changes - though in this case, guidance authors sometimes choose to create a new benchmark entirely.
ExampleAn InSpec control did not properly address a caveat specified by the guidance. Making the fix bumps the profile from v1.3.4 to v1.3.5.DISA publishes a new version of the RHEL 8 STIG going from V1R13 to V1R14 in order to adjust the check text command syntax for several sshd configuration related requirements amongst other things. Making the changes bumps the profile from v1.13.4 to v1.14.0.DISA adds, removes, and modifies a substantial number of requirements due to transitioning between control versions (NIST SP 800-53 Rev. 4 to Rev. 5). Making the changes bumps the profile from v1.6.1 to v2.0.0.
+ +## Understanding Update Scope + +Important concepts to remember: + +- Updates are version-specific +- Changes only move forward ("forward-only" process) +- No "back-patching" to older versions +- Each requirement maps to: + - Source SRG document + - Control Correlation Identifier (CCI) + - Unique Rule and STIG IDs + +Example requirement identifiers: + +```ruby +tag gtitle: 'SRG-OS-000480-GPOS-00227' +tag gid: 'V-230221' +tag rid: 'SV-230221r858734_rule' +tag stig_id: 'RHEL-08-010000' +tag fix_id: 'F-32865r567410_fix' +tag cci: ['CCI-000366'] +``` From 357529aef8886eda290b9ed277936d407490af13 Mon Sep 17 00:00:00 2001 From: Amndeep Singh Mann Date: Thu, 12 Dec 2024 10:08:49 -0800 Subject: [PATCH 17/27] pg 12-14 - update types Signed-off-by: Amndeep Singh Mann --- src/courses/profile-dev-test/12.md | 7 +- src/courses/profile-dev-test/13.md | 24 ++++-- src/courses/profile-dev-test/14.md | 130 +++++++++++++++++++++++++++-- 3 files changed, 142 insertions(+), 19 deletions(-) diff --git a/src/courses/profile-dev-test/12.md b/src/courses/profile-dev-test/12.md index c4d8ca942..edd015781 100644 --- a/src/courses/profile-dev-test/12.md +++ b/src/courses/profile-dev-test/12.md @@ -1,7 +1,7 @@ --- order: 12 next: 13.md -title: Understanding Profile Patch Updates +title: 12. Understanding Profile Patch Updates author: Aaron Lippold --- @@ -43,7 +43,10 @@ A patch update is a minor modification to an InSpec profile that addresses speci - Control logic - `inspec.yml` inputs - Threshold values -- Note: The InSpec version in `inspec.yml` is managed during release + +::: note Version number increments +The version attribute in `inspec.yml` is managed during releases so you shouldn't change it in every merged branch, just when you cut a new release. +::: ### 4. Testing Protocol diff --git a/src/courses/profile-dev-test/13.md b/src/courses/profile-dev-test/13.md index 42cf4ecd9..a881fc230 100644 --- a/src/courses/profile-dev-test/13.md +++ b/src/courses/profile-dev-test/13.md @@ -1,7 +1,7 @@ --- order: 13 next: 14.md -title: Understanding Release Updates in SAF +title: 13. Understanding Release Updates author: Aaron Lippold --- @@ -13,31 +13,33 @@ author: Aaron Lippold ## What is a Release Update? -A Release Update is a structured process for updating Security Automation Framework (SAF) profiles to accommodate new benchmark versions. This process ensures consistent quality and maintains traceability of changes. +A Release Update is a structured process for updating a profile to accommodate a new benchmark version. This process ensures consistent quality and maintains traceability of changes. ## Release Update Workflow ### Step 1: Branch Creation -Create a new branch named `v#{x}R#{x+1}` from either: +Create a new branch named `v{x}r{xx}` from either: - The main branch -- Latest patch release branch +- The tagged commit associated with the latest release ### Step 2: Generate Delta -Run the `saf generate delta` workflow to update: +Run the `saf generate delta` workflow to automatically update the InSpec profile as per the new guidance. Items that get updated include: - Control metadata - inspec.yml configuration - README.md documentation - Other profile elements -> Note: This process preserves existing `describe` blocks and Ruby code logic +::: info Saved! +This process preserves existing `describe` blocks and other Ruby code logic, but you will still need to review them to ensure that what they're assessing still lines up with what the requirement says we now need to be assessing. +::: ### Step 3: Change Management -Follow these best practices to organize your work: +Follow these best practices to organize your work as you implement any new requirements and update any changed ones: #### 3.1 Control Tracking @@ -56,13 +58,17 @@ Follow these best practices to organize your work: - [ ] Documentation current 2. **Infrastructure Updates** - - Update hardening content: + - Update the version of the hardening content that is used to test the InSpec profile to match the version of the benchmark: - Ansible playbooks - Puppet modules - Chef cookbooks - Docker images - Vagrant boxes +::: important Parallel workstreams +You might be required to update the hardening content itself to match the new or adjusted requirements coming from the benchmark instead of just consuming the newest version. However, updating the hardening and validation content lock-step is a straightforward process! +::: + 3. **Metadata Management** - Update all version references - Verify control titles @@ -71,7 +77,7 @@ Follow these best practices to organize your work: ## Tips for Success - Focus on controls with modified `check text` or `fix text` -- Unchanged control text typically means no code changes needed +- Unchanged control text typically means no code changes are needed - Use PR links to track changes in your tracking table - Maintain CI/CD pipeline health throughout updates diff --git a/src/courses/profile-dev-test/14.md b/src/courses/profile-dev-test/14.md index 50bd5ff2a..8206f8ff9 100644 --- a/src/courses/profile-dev-test/14.md +++ b/src/courses/profile-dev-test/14.md @@ -1,13 +1,8 @@ --- order: 14 next: 15.md -title: Understanding Major Version Updates +title: 14. Understanding Major Version Updates author: Aaron Lippold -difficulty: Advanced -prerequisites: - - Basic InSpec knowledge - - Understanding of STIG benchmarks - - Familiarity with Ruby --- ## Learning Objectives @@ -26,7 +21,7 @@ A Major Version Update occurs when transitioning to a new STIG Benchmark version ### Requirement Alignment -:::tip 💡 **Pro Tip**: Create a spreadsheet to track your requirement mappings during the alignment process. +:::tip Create a spreadsheet to track your requirement mappings during the alignment process. ::: When moving between major versions (e.g., RHEL 8 v1R12 to RHEL 9 V1R1), we need to align existing tests with new requirements using: @@ -54,7 +49,126 @@ When moving between major versions (e.g., RHEL 8 v1R12 to RHEL 9 V1R1), we need ### Practical Example -Consider this simplified alignment scenario: +Consider this alignment scenario where we are updating from RHEL8 to RHEL9. + +The requirements are the same: the `/var/log/messages` file must be owned by root. However, despite being the same, each requirement has its own id. Consequently, we need to use alternative means to realize that these requirements are aligned. + +Attributes to consider: + - The title is almost the same aside from the operating system version. + - The description is almost exactly the same aside from inconsequential differences. + - Whitespace + - Version number + - Capitalization + - Other alignment IDs are the same. + - SRG ID / `gtitle`: SRG-OS-000206-GPOS-00084 + - CCI: CCI-001314 + - NIST: SI-11 b + - Check and fix text + - Fix text is the same + - Check text specifies a different method to do the assessment, but they're functionally equivalent + +::: code-tab +@tab RHEL8 +```ruby +control 'SV-230246' do + title 'The RHEL 8 /var/log/messages file must be owned by root.' + desc "Only authorized personnel should be aware of errors and the details of +the errors. Error messages are an indicator of an organization's operational +state or can identify the RHEL 8 system or platform. Additionally, Personally +Identifiable Information (PII) and operational information must not be revealed +through error messages to unauthorized personnel or their designated +representatives. + + The structure and content of error messages must be carefully considered by +the organization and development team. The extent to which the information +system is able to identify and handle error conditions is guided by +organizational policy and operational requirements." + desc 'check', 'Verify that the /var/log/messages file is owned by root with the following +command: + + $ sudo stat -c "%U" /var/log/messages + + root + + If "root" is not returned as a result, this is a finding.' + desc 'fix', 'Change the owner of the file /var/log/messages to root by running the +following command: + + $ sudo chown root /var/log/messages' + impact 0.5 + ref 'DPMS Target Red Hat Enterprise Linux 8' + tag severity: 'medium' + tag gtitle: 'SRG-OS-000206-GPOS-00084' + tag gid: 'V-230246' + tag rid: 'SV-230246r627750_rule' + tag stig_id: 'RHEL-08-010220' + tag fix_id: 'F-32890r567485_fix' + tag cci: ['CCI-001314'] + tag nist: ['SI-11 b'] + tag 'host' + + only_if('This control is Not Applicable to containers', impact: 0.0) { + !virtualization.system.eql?('docker') + } + + describe.one do + describe file('/var/log/messages') do + it { should be_owned_by 'root' } + end + describe file('/var/log/messages') do + it { should_not exist } + end + end +end +``` +@tab RHEL9 +```ruby +control 'SV-257916' do + title 'RHEL 9 /var/log/messages file must be owned by root.' + desc "Only authorized personnel should be aware of errors and the details of the errors. Error messages are an indicator of an organization's operational state or can identify the RHEL 9 system or platform. Additionally, personally identifiable information (PII) and operational information must not be revealed through error messages to unauthorized personnel or their designated representatives. + +The structure and content of error messages must be carefully considered by the organization and development team. The extent to which the information system is able to identify and handle error conditions is guided by organizational policy and operational requirements." + desc 'check', 'Verify the "/var/log/messages" file is owned by root with the following command: + +$ ls -la /var/log/messages + +rw-------. 1 root root 564223 July 11 11:34 /var/log/messages + +If "/var/log/messages" does not have an owner of "root", this is a finding.' + desc 'fix', 'Change the owner of the "/var/log/messages" file to "root" by running the following command: + +$ sudo chown root /var/log/messages' + impact 0.5 + ref 'DPMS Target Red Hat Enterprise Linux 9' + tag severity: 'medium' + tag gtitle: 'SRG-OS-000206-GPOS-00084' + tag gid: 'V-257916' + tag rid: 'SV-257916r925735_rule' + tag stig_id: 'RHEL-09-232180' + tag fix_id: 'F-61581r925734_fix' + tag cci: ['CCI-001314'] + tag nist: ['SI-11 b'] + tag 'host' + + only_if('This control is Not Applicable to containers', impact: 0.0) { + !virtualization.system.eql?('docker') + } + + describe.one do + describe file('/var/log/messages') do + it { should be_owned_by 'root' } + end + describe file('/var/log/messages') do + it { should_not exist } + end + end +end +``` +::: + +::: tip Different yet the same +Even though the check text changed, it doesn't mean that the InSpec code needs to as well! We are still correctly assessing that the `/var/log/messages` file is owned by root if it exists. +::: ## Best Practices From 0f658f40706c8dd2330622123d0c517d5fce6657 Mon Sep 17 00:00:00 2001 From: Amndeep Singh Mann Date: Thu, 12 Dec 2024 10:16:37 -0800 Subject: [PATCH 18/27] fix syntax Signed-off-by: Amndeep Singh Mann --- src/courses/profile-dev-test/14.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/courses/profile-dev-test/14.md b/src/courses/profile-dev-test/14.md index 8206f8ff9..d3c39b559 100644 --- a/src/courses/profile-dev-test/14.md +++ b/src/courses/profile-dev-test/14.md @@ -67,7 +67,7 @@ Attributes to consider: - Fix text is the same - Check text specifies a different method to do the assessment, but they're functionally equivalent -::: code-tab +::: code-tabs#shell @tab RHEL8 ```ruby control 'SV-230246' do From 201029de39a986870e7fb1552c7012a7b96a2f8d Mon Sep 17 00:00:00 2001 From: Will Date: Thu, 12 Dec 2024 10:32:37 -0800 Subject: [PATCH 19/27] rhel8 --> rhel9 Signed-off-by: Will --- src/courses/advanced/03.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/courses/advanced/03.md b/src/courses/advanced/03.md index a04600b8c..f0b4d1741 100644 --- a/src/courses/advanced/03.md +++ b/src/courses/advanced/03.md @@ -23,7 +23,7 @@ Which will return something like: ```sh CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES -8bs80z6b5n9s redhat/ubi8 "/bin/bash" 2 weeks ago Up 1 hour redhat8 +8bs80z6b5n9s redhat/ubi9 "/bin/bash" 2 weeks ago Up 1 hour redhat9 8ba6b8av5n7s nginx:latest "/docker.…" 2 weeks ago Up 1 hour 80/tcp nginx ``` @@ -100,7 +100,7 @@ inputs: - admin ``` -You should have an inputs file in your profile at `inputs-linux.yml` +You should have an inputs file in your profile, at `my_nginx/inputs.yml`. It should say the following: ```yaml admin_users: From 2c6a8d70e8e09858eb638ffe2251217885beff8e Mon Sep 17 00:00:00 2001 From: Amndeep Singh Mann Date: Thu, 12 Dec 2024 22:04:07 -0800 Subject: [PATCH 20/27] all the test kitchen ones Signed-off-by: Amndeep Singh Mann --- src/courses/profile-dev-test/15.md | 8 +- src/courses/profile-dev-test/16.md | 3 +- src/courses/profile-dev-test/17.md | 35 +++--- src/courses/profile-dev-test/18.md | 11 +- src/courses/profile-dev-test/19.md | 2 +- src/courses/profile-dev-test/20.md | 115 ++++++++++++++++-- src/courses/profile-dev-test/21.md | 179 +++++++++++++++++++---------- src/courses/profile-dev-test/22.md | 150 ++++++++++++------------ src/courses/profile-dev-test/23.md | 120 ------------------- 9 files changed, 330 insertions(+), 293 deletions(-) delete mode 100644 src/courses/profile-dev-test/23.md diff --git a/src/courses/profile-dev-test/15.md b/src/courses/profile-dev-test/15.md index 7b634b18f..83070fb4d 100644 --- a/src/courses/profile-dev-test/15.md +++ b/src/courses/profile-dev-test/15.md @@ -1,7 +1,7 @@ --- order: 15 next: 16.md -title: Understanding Test Kitchen +title: 15. Understanding Test Kitchen author: Aaron Lippold --- @@ -77,8 +77,6 @@ We use two main testing configurations: Failed: 1: Passed: 5: ``` - ## Behind the Scenes: System Access @@ -88,3 +86,7 @@ To enable testing, Test Kitchen makes minimal system modifications: - Sets up appropriate access protocols: - SSH for Unix/Linux systems - WinRM for Windows systems + +## Where do we put it? + +We put our Test Kitchen code that we use to assess our InSpec code in the same repository. The example that we will be working through for the next few sections will use the [RHEL 9 InSpec repository](https://github.com/mitre/redhat-enterprise-linux-9-stig-baseline). diff --git a/src/courses/profile-dev-test/16.md b/src/courses/profile-dev-test/16.md index 0dc021f15..31f50c925 100644 --- a/src/courses/profile-dev-test/16.md +++ b/src/courses/profile-dev-test/16.md @@ -1,9 +1,8 @@ --- order: 16 next: 17.md -title: Test Kitchen - Understanding the Create Stage +title: 16. Test Kitchen - Create author: Aaron Lippold -index: true --- ## Test Kitchen Create Stage diff --git a/src/courses/profile-dev-test/17.md b/src/courses/profile-dev-test/17.md index 488cb1e1a..052859db7 100644 --- a/src/courses/profile-dev-test/17.md +++ b/src/courses/profile-dev-test/17.md @@ -1,9 +1,8 @@ --- order: 17 next: 18.md -title: Test Kitchen - Converge +title: 17. Test Kitchen - Converge author: Aaron Lippold -index: true --- ## Learning Objectives @@ -18,7 +17,9 @@ By the end of this section, you will understand: The `converge` stage applies system configurations using infrastructure as code (IaC) tools. This crucial stage transforms your environment from a base state to your desired configuration. -> **Key Concept**: Think of the converge stage as "applying your recipe" - it takes your raw ingredients (base system) and follows your instructions to create the final dish (configured system). +::: info Let 'em cook +Think of the converge stage as "applying your recipe" - it takes your raw ingredients (base system) and follows your instructions to create the final dish (configured system). +::: Supported configuration tools include: @@ -44,44 +45,46 @@ We implement two distinct configurations using 'wrapper playbooks': - Ansible Galaxy dependencies - Custom roles and requirements -> **Note**: While some hardening tasks are disabled for testing, this doesn't compromise our security validation goals. +::: note While some hardening tasks are disabled for testing, this doesn't compromise our security validation goals. +::: + +## Hands-on Practice -## Container Converge +### Container Converge -Our container strategy utilizes two RedHat UBI8 (Universal Base Image) variants: +Our container strategy utilizes two Red Hat UBI9 (Universal Base Image) variants. Take a look at the SAF's [RHEL9 InSpec profile](https://github.com/mitre/redhat-enterprise-linux-9-stig-baseline/tree/main) which also includes our Test Kitchen and Ansible code that we use to test that our InSpec tests work properly. 1. **Vanilla Container** -This container uses the `registry.access.redhat.com/ubi8/ubi:8.9-1028` image from RedHat's community repositories. +This container uses the `registry.access.redhat.com/ubi9/ubi:9.3-1610` image from RedHat's community repositories. It represents a standard, out-of-the-box configuration. - - Community maintained - Standard configuration -1. **Hardened Container** -hardened: This container uses the `registry1.dso.mil/ironbank/redhat/ubi/ubi8` image from Red Hat's Platform One Iron Bank project. +2. **Hardened Container** -It represents a security-enhanced configuration. +This container uses the `registry1.dso.mil/ironbank/redhat/ubi/ubi9` image from Red Hat's Platform One Iron Bank project. +It represents a security-enhanced configuration. - STIG-compliant - Regular security updates - Platform One certified -## Hands-on Practice Try these exercises: 1. Compare the contents of vanilla and hardened playbooks -2. Identify key security configurations in the RHEL8-STIG role +2. Identify key security configurations in the RHEL9-STIG role 3. Examine the wrapper playbook structure in the spec/ directory -### Summary +## Summary - Converge stage implements your desired system configurations - Multiple implementation tools available (Ansible, Puppet, Chef, etc.) - Two primary configurations: vanilla (baseline) and hardened (security-enhanced) -- Container implementations use RedHat UBI8 images with different security postures +- Container implementations use different images with different security postures -::: info Next Steps: Practice running the converge stage with both vanilla and hardened configurations to understand the differences in outcomes. +::: info Next Steps +Practice running the converge stage with both vanilla and hardened configurations to understand the differences in outcomes. ::: diff --git a/src/courses/profile-dev-test/18.md b/src/courses/profile-dev-test/18.md index 02b48d4fa..867acde6e 100644 --- a/src/courses/profile-dev-test/18.md +++ b/src/courses/profile-dev-test/18.md @@ -1,16 +1,17 @@ --- order: 18 next: 19.md -title: Test Kitchen - Validate +title: 18. Test Kitchen - Verify author: Aaron Lippold -index: true --- -## Test Kitchen Validate Stage +## Test Kitchen Verify Stage -The `verify` stage uses the `kitchen-inspec` verifier from Test Kitchen to run the inspec profile against the test targets. +The `verify` stage is when we are able to use Test Kitchen to validate that our InSpec profile was written properly. -For this stage, the inspec profile receives a set of tailored `input` YAML files. These files adjust the testing for each target, ensuring accurate validation against the expected state and minimizing false results. +The `verify` stage uses the `kitchen-inspec` verifier from Test Kitchen to run the InSpec profile against the test targets. + +For this stage, the InSpec profile receives a set of tailored `input` YAML files. These files adjust the testing for each target, ensuring accurate validation against the expected state and minimizing incorrect results. They are located at the root of the project and are named something like `kitchen.inputs.yml`. diff --git a/src/courses/profile-dev-test/19.md b/src/courses/profile-dev-test/19.md index 08e0f12d0..382de54a2 100644 --- a/src/courses/profile-dev-test/19.md +++ b/src/courses/profile-dev-test/19.md @@ -1,7 +1,7 @@ --- order: 19 next: 20.md -title: Test Kitchen - Destroy +title: 19. Test Kitchen - Destroy author: Aaron Lippold --- diff --git a/src/courses/profile-dev-test/20.md b/src/courses/profile-dev-test/20.md index 45ace5336..7f4af4c96 100644 --- a/src/courses/profile-dev-test/20.md +++ b/src/courses/profile-dev-test/20.md @@ -1,24 +1,117 @@ --- order: 20 next: 21.md -title: Test Kitchen - .kitchen/ Directory +title: 20. Test Kitchen - `kitchen.yml` File author: Aaron Lippold --- -## The `.kitchen/` Directory +## Understanding the `kitchen.yml` File -The [`.kitchen/`](/.kitchen/) directory contains the state files for Test Kitchen. These files are automatically generated when you first run Test Kitchen. +The [`kitchen.yml`](./kitchen.yml) file is the primary configuration file for Test Kitchen. It outlines the shared configuration for all your testing environments, platforms, and the testing framework to be used. -### Understanding the `.kitchen/` Directory +Each of the subsequent Kitchen files will inherit the shared settings from this file automatically and merge them with the settings in the child Kitchen file. -The `.kitchen/` directory is crucial for managing the state of your Test Kitchen instances. It includes configuration and state information that Test Kitchen uses to manage your test environments. +## Example `kitchen.yml` File -### Using the `.kitchen/` Directory +```yaml +--- +verifier: + name: inspec + sudo: true + reporter: + - cli + - json:spec/results/%{platform}_%{suite}.json + inspec_tests: + - name: RedHat 9 STIG v1r2 + path: . + input_files: + - kitchen.inputs.yml + <% if ENV['INSPEC_CONTROL'] %> + controls: + - "<%= ENV['INSPEC_CONTROL'] %>" + <% end %> + load_plugins: true + env_vars: + - "CHEF_LICENSE=<%= ENV['CHEF_LICENSE'] %>" + +suites: + - name: vanilla + provisioner: + playbook: spec/ansible/roles/ansible-role-rhel-vanilla.yml + + - name: hardened + provisioner: + playbook: spec/ansible/roles/ansible-role-rhel-hardened.yml + +transport: + max_ssh_sessions: 6 +``` + +# Breakdown of the `kitchen.yml` file + +```yaml +--- +verifier: + name: inspec + sudo: true + reporter: + - cli + - json:spec/results/%{platform}_%{suite}.json + inspec_tests: + - name: RedHat 9 STIG v1r2 + path: . + input_files: + - kitchen.inputs.yml + <% if ENV['INSPEC_CONTROL'] %> + controls: + - "<%= ENV['INSPEC_CONTROL'] %>" + <% end %> + load_plugins: true + env_vars: + - "CHEF_LICENSE=<%= ENV['CHEF_LICENSE'] %>" +``` + +This first section configures the verifier, which is the tool that checks if your system is in the desired state. Here, it's using InSpec. + +- `sudo: true` means that InSpec will run with sudo privileges. +- `reporter` specifies the formats in which the test results will be reported. Here, it's set to report in the command-line interface (`cli`) and in a JSON file (`json:spec/results/%{platform}_%{suite}.json`). Note that variables will be templated into this filename by Kitchen to help you differentiate between the different testing configurations you're iterating over. +- `inspec_tests` specifies the InSpec profiles to run. Here, it's running the "RedHat 9 STIG v1r2" profile located in the current directory (`path: .`). +- `input_files` specifies files that contain input variables for the InSpec profile. Here, it's using the `kitchen.inputs.yml` file. +- The `controls` section is dynamically set based on the `INSPEC_CONTROL` environment variable. If the variable is set, only the specified control will be run. +- `load_plugins: true` means that InSpec will load any available plugins. + +```yaml +suites: + - name: vanilla + provisioner: + playbook: spec/ansible/roles/ansible-role-rhel-vanilla.yml + + - name: hardened + provisioner: + playbook: spec/ansible/roles/ansible-role-rhel-hardened.yml +``` + +This section defines the test suites. Each suite represents a different configuration to test. + +- Each suite has a `name` and a `provisioner`. +- The `provisioner` section specifies the Ansible playbook to use for the suite. Here, it's using the `ansible-role-rhel-vanilla.yml` playbook for the "vanilla" suite and the `ansible-role-rhel-hardened.yml` playbook for the "hardened" suite. + +```yaml +transport: + max_ssh_sessions: 6 +``` + +The last section allows you to configure attributes of the transport. In this case, we're setting the maximum number of parallel SSH sessions. + +## Environment Variables in `kitchen.yml` + +- `INSPEC_CONTROL`: This variable allows you to specify a single control to run during the `bundle exec kitchen verify` phase. This is particularly useful for testing or debugging a specific requirement. -Refer to the [Finding Your Test Target Login Details](#311-locating-test-target-login-details) section to learn how to use the `.kitchen/` directory effectively. This section will guide you on locating and utilizing the login details for your test targets stored within this directory. +# Recap on Kitchen Stages -### Key Points to Remember +The workflow of Test Kitchen involves the following steps: -- The `.kitchen/` directory is automatically created when you run Test Kitchen for the first time. -- It stores state and configuration files necessary for managing test environments. -- Understanding the contents of this directory can help you troubleshoot and manage your test instances more effectively. +1. **Create:** Test Kitchen uses the driver to create an instance of the platform. +2. **Converge:** Test Kitchen uses the provisioner to apply the infrastructure code to the instance. In this case, it's using Ansible playbooks. +3. **Verify:** Test Kitchen uses the verifier to check if the instance is in the desired state. +4. **Destroy:** Test Kitchen uses the driver to destroy the instance after testing. This is not shown in your file. diff --git a/src/courses/profile-dev-test/21.md b/src/courses/profile-dev-test/21.md index 08250aaa0..2ad522407 100644 --- a/src/courses/profile-dev-test/21.md +++ b/src/courses/profile-dev-test/21.md @@ -1,100 +1,157 @@ --- -order: 21 -next: 22.md -title: Test Kitchen - `kitchen.yml` File +order: 22 +next: 23.md +title: Test Kitchen - `kitchen.ec2.yml` File author: Aaron Lippold --- -## Understanding the `kitchen.yml` File +## Understanding the `kitchen.ec2.yml` File -The [`kitchen.yml`](./kitchen.yml) file is the primary configuration file for Test Kitchen. It outlines the shared configuration for all your testing environments, platforms, and the testing framework to be used. +The `kitchen.ec2.yml` file is instrumental in setting up our testing targets within the AWS environment. It outlines the configuration details for these targets, including their VPC assignments and the specific settings for each VPC. -Each of the subsequent kitchen files will inherit the shared settings from this file automatically and merge them with the settings in the child kitchen file. +This file leverages the AWS CLI and your AWS credentials, environment variables, and settings that you should have configured as described in the [Environment Setup Guide](./03.md) section. -## Example `kitchen.yml` File +## Example `kitchen.ec2.yml` File ```yaml --- -verifier: - name: inspec - sudo: true - reporter: - - cli - - json:spec/results/%{platform}_%{suite}.json - inspec_tests: - - name: RedHat 8 STIG v1r12 - path: . - input_files: - - kitchen.inputs.yml - <% if ENV['INSPEC_CONTROL'] %> - controls: - - "<%= ENV['INSPEC_CONTROL'] %>" - <% end %> - load_plugins: true +platforms: + - name: rhel-9 + +driver: + name: ec2 + subnet_id: "<%= ENV['SAF_PIPELINE_SUBNET'] %>" + security_group_ids: + - "<%= ENV['SAF_PIPELINE_SG'] %>" + metadata_options: + http_tokens: required + http_put_response_hop_limit: 1 + instance_metadata_tags: enabled + instance_type: t2.small + associate_public_ip: true + interface: public + skip_cost_warning: true + privileged: true + instance_initiated_shutdown_behavior: terminate + +provisioner: + name: ansible_playbook + hosts: all + require_chef_for_busser: false + require_ruby_for_busser: false + ansible_binary_path: /usr/local/bin + # require_pip3: true + ansible_verbose: true + roles_path: spec/ansible/roles + galaxy_ignore_certs: true + requirements_path: spec/ansible/roles/requirements.yml + requirements_collection_path: spec/ansible/roles/requirements.yml + ansible_extra_flags: <%= ENV['ANSIBLE_EXTRA_FLAGS'] %> suites: - name: vanilla provisioner: playbook: spec/ansible/roles/ansible-role-rhel-vanilla.yml + driver: + tags: + Name: Vanilla-<%= ENV['USER'] %> + CreatedBy: test-kitchen + - name: hardened provisioner: playbook: spec/ansible/roles/ansible-role-rhel-hardened.yml + driver: + tags: + Name: Hardened-<%= ENV['USER'] %> + CreatedBy: test-kitchen + +lifecycle: + pre_converge: + - remote: | + # echo "+++ Refreshing DNF package cache +++" + # sudo dnf -y clean all + echo "" + echo "+++ Updating DNF Packages +++" + sudo dnf -y update --nogpgcheck --nobest + echo "" + echo "+++ Installing needed packages for workflow and utility +++\n\n" + sudo dnf -y install --nogpgcheck bc bind-utils redhat-lsb-core vim git wget gcc openssl-devel libffi-devel bzip2-devel + echo "" + echo "+++ Installing Python 3.9 and Ansible +++\n\n" + export PATH=/usr/local/bin:$PATH + sudo dnf -y install python3-pip + sudo python3 -m pip install ansible jmespath + echo "" + echo "+++ Updating the ec2-user to keep sudo working after hardening phase +++\n\n" + sudo chage -d $(( $( date +%s ) / 86400 )) ec2-user + echo "" + echo "+++ updating ec2-user sudo config for hardening phase +++\n\n" + sudo chmod 600 /etc/sudoers && sudo sed -i'' "/ec2-user/d" /etc/sudoers && sudo chmod 400 /etc/sudoers + sudo dnf -y install git + echo "+++ add cinc-auditor for local shell +++\n\n" + curl -L https://omnitruck.cinc.sh/install.sh | sudo bash -s -- -P cinc-auditor + +transport: + name: ssh + #https://github.com/neillturner/kitchen-ansible/issues/295 + max_ssh_sessions: 2 ``` -# Breakdown of the `kitchen.yml` file +# Breakdown of the `kitchen.ec2.yml` file ```yaml -verifier: - name: inspec - sudo: true - reporter: - - cli - - json:spec/results/%{platform}_%{suite}.json - inspec_tests: - - name: RedHat 8 STIG v1r12 - path: . - input_files: - - kitchen.inputs.yml - <% if ENV['INSPEC_CONTROL'] %> - controls: - - "<%= ENV['INSPEC_CONTROL'] %>" - <% end %> - load_plugins: true +platforms: + - name: rhel-9 ``` -This first section configures the verifier, which is the tool that checks if your system is in the desired state. Here, it's using InSpec. +This section defines the platforms on which your tests will run. In this case, it's Red Hat Enterprise Linux 9. -- `sudo: true` means that InSpec will run with sudo privileges. -- `reporter` specifies the formats in which the test results will be reported. Here, it's set to report in the command-line interface (`cli`) and in a JSON file (`json:spec/results/%{platform}_%{suite}.json`). -- `inspec_tests` specifies the InSpec profiles to run. Here, it's running the "RedHat 8 STIG v1r12" profile located in the current directory (`path: .`). -- `input_files` specifies files that contain input variables for the InSpec profile. Here, it's using the `kitchen.inputs.yml` file. -- The `controls` section is dynamically set based on the `INSPEC_CONTROL` environment variable. If the variable is set, only the specified control will be run. -- `load_plugins: true` means that InSpec will load any available plugins. +```yaml +driver: + name: ec2 + ... +``` + +This section configures the driver, which is responsible for creating and managing the instances. Here, it's set to use Amazon EC2 instances. The various options configure the EC2 instances, such as instance type (`t2.small`), whether to associate a public IP address (`associate_public_ip: true`), and various metadata options. + +```yaml +provisioner: + name: ansible_playbook + ... +``` + +This section configures the provisioner, which is the tool that brings your system to the desired state. Here, it's using Ansible playbooks. The various options configure how Ansible is run, such as the path to the Ansible binary (`ansible_binary_path: /usr/local/bin`) and the paths to the roles and requirements files. ```yaml suites: - name: vanilla - provisioner: - playbook: spec/ansible/roles/ansible-role-rhel-vanilla.yml - - name: hardened - provisioner: - playbook: spec/ansible/roles/ansible-role-rhel-hardened.yml + ... ``` -This section defines the test suites. Each suite represents a different configuration to test. +This section configures the test suites, which are the various configurations that are being tested. Here, we outline how to spin up our vanilla and hardened containers. Each suite contains various options such as one to specify the path to the playbook that the provisioner should use. -- Each suite has a `name` and a `provisioner`. -- The `provisioner` section specifies the Ansible playbook to use for the suite. Here, it's using the `ansible-role-rhel-vanilla.yml` playbook for the "vanilla" suite and the `ansible-role-rhel-hardened.yml` playbook for the "hardened" suite. +```yaml +lifecycle: + pre_converge: + - remote: | + ... +``` -## Environment Variables in `kitchen.yml` +This section defines lifecycle hooks, which are commands that run at certain points in the Test Kitchen run. Here, it's running a series of commands before the converge phase (i.e., before applying the infrastructure code). These commands install necessary packages, update system packages, and update the `ec2-user` configuration. -- `INSPEC_CONTROL`: This variable allows you to specify a single control to run during the `bundle exec kitchen verify` phase. This is particularly useful for testing or debugging a specific requirement. +```yaml +transport: + name: ssh + max_ssh_sessions: 2 +``` -# Recap on Kitchen Stages +This section configures the transport, which is the method Test Kitchen uses to communicate with the instance. Here, it's using SSH and allowing a maximum of 2 SSH sessions. The workflow of Test Kitchen involves the following steps: 1. **Create:** Test Kitchen uses the driver to create an instance of the platform. -2. **Converge:** Test Kitchen uses the provisioner to apply the infrastructure code to the instance. In this case, it's using Ansible playbooks. -3. **Verify:** Test Kitchen uses the verifier to check if the instance is in the desired state. -4. **Destroy:** Test Kitchen uses the driver to destroy the instance after testing. This is not shown in your file. +2. **Converge:** Test Kitchen uses the provisioner to apply the infrastructure code to the instance. Before this phase, it runs the commands defined in the `pre_converge` lifecycle hook. +3. **Verify:** Test Kitchen checks if the instance is in the desired state. This is not shown in your file, but it would be configured in the `verifier` section. +4. **Destroy:** Test Kitchen uses the driver to destroy the instance after testing. This is not shown in your file, but it would be configured in the `driver` section. + +The `transport` is used in all these steps to communicate with the instance. diff --git a/src/courses/profile-dev-test/22.md b/src/courses/profile-dev-test/22.md index 46d0f2d61..c3555ebd2 100644 --- a/src/courses/profile-dev-test/22.md +++ b/src/courses/profile-dev-test/22.md @@ -1,118 +1,120 @@ --- order: 22 next: 23.md -title: Test Kitchen - `kitchen.ec2.yml` File +title: 22. Test Kitchen - `kitchen.container.yml` File author: Aaron Lippold --- -## Understanding the `kitchen.ec2.yml` File +## Understanding the `kitchen.container.yml` File -The `kitchen.ec2.yml` file is instrumental in setting up our testing targets within the AWS environment. It outlines the configuration details for these targets, including their VPC assignments and the specific settings for each VPC. +The `kitchen.container.yml` file orchestrates our container-based test suite. It defines two types of containers: hardened and vanilla, and specifies the InSpec tests to run against them. It also configures the generation and storage of test reports. -This file leverages the `AWS CLI and AWS Credentials` configured as described in the previous [Required Software](#13-required-software) section. +Unlike other test suites, the container suite skips the 'provisioner' stage for the vanilla and hardened targets. Instead, during the create stage, it simply downloads and starts the specified images. This is due to the use of the [dummy Test Kitchen driver](https://github.com/test-kitchen/test-kitchen/blob/main/lib/kitchen/driver/dummy.rb), which is ideal for interacting with pre-configured or immutable targets like containers. -Alternatively, if you've set up AWS Environment Variables, the file will use those for AWS interactions. +This approach allows for the evaluation of existing containers, even those created by other workflows. It can be leveraged to build a generalized workflow for validating any container against our Benchmark requirements, providing a comprehensive assessment of its security posture. -## Example `kitchen.ec2.yml` File +## Example `kitchen.container.yml` file ```yaml --- -platforms: - - name: rhel-8 - -driver: - name: ec2 - metadata_options: - http_tokens: required - http_put_response_hop_limit: 1 - instance_metadata_tags: enabled - instance_type: m5.large - associate_public_ip: true - interface: public - skip_cost_warning: true - privileged: true - tags: - CreatedBy: test-kitchen +# see: https://kitchen.ci/docs/drivers/dokken/ provisioner: - name: ansible_playbook - hosts: all - require_chef_for_busser: false - require_ruby_for_busser: false - ansible_binary_path: /usr/local/bin - require_pip3: true - ansible_verbose: true - roles_path: spec/ansible/roles - galaxy_ignore_certs: true - requirements_path: spec/ansible/roles/requirements.yml - ansible_extra_flags: <%= ENV['ANSIBLE_EXTRA_FLAGS'] %> - -lifecycle: - pre_converge: - - remote: | - echo "NOTICE - Installing needed packages" - sudo dnf -y clean all - sudo dnf -y install --nogpgcheck bc bind-utils redhat-lsb-core vim - echo "updating system packages" - sudo dnf -y update --nogpgcheck --nobest - sudo dnf -y distro-sync - echo "NOTICE - Updating the ec2-user to keep sudo working" - sudo chage -d $(( $( date +%s ) / 86400 )) ec2-user - echo "NOTICE - updating ec2-user sudo config" - sudo chmod 600 /etc/sudoers && sudo sed -i'' "/ec2-user/d" /etc/sudoers && sudo chmod 400 /etc/sudoers + name: dummy + +driver: + name: dokken + pull_platform_image: false transport: - name: ssh - max_ssh_sessions: 2 + name: dokken + +platforms: + - name: ubi9 + +suites: + - name: vanilla + driver: + image: <%= ENV['VANILLA_CONTAINER_IMAGE'] || "registry.access.redhat.com/ubi9/ubi:9.3-1610" %> + verifier: + input_files: + - container.vanilla.inputs.yml + - name: hardened + driver: + image: <%= ENV['HARDENED_CONTAINER_IMAGE'] || "registry1.dso.mil/ironbank/redhat/ubi/ubi9" %> + verifier: + input_files: + - container.hardened.inputs.yml + # creds_file: './creds.json' ``` -# Breakdown of the `kitchen.ec2.yml` file +# Breakdown of the `kitchen.container.yml` file ```yaml -platforms: - - name: rhel-8 +provisioner: + name: dummy ``` -This section defines the platforms on which your tests will run. In this case, it's Red Hat Enterprise Linux 8. +This section configures the provisioner, which is the tool that brings your system to the desired state. Here, it's using the dummy provisioner, which means no provisioning will be done. ```yaml driver: - name: ec2 - ... + name: dokken + pull_platform_image: false ``` -This section configures the driver, which is responsible for creating and managing the instances. Here, it's set to use Amazon EC2 instances. The various options configure the EC2 instances, such as instance type (`m5.large`), whether to associate a public IP address (`associate_public_ip: true`), and various metadata options. +This section configures the driver, which is responsible for creating and managing the instances. Here, it's set to use the Dokken driver, which is designed for running tests in Docker containers. The `pull_platform_image: false` option means that it won't automatically pull the Docker image for the platform; it will use the image specified in the suite. ```yaml -provisioner: - name: ansible_playbook - ... +transport: + name: dokken ``` -This section configures the provisioner, which is the tool that brings your system to the desired state. Here, it's using Ansible playbooks. The various options configure how Ansible is run, such as the path to the Ansible binary (`ansible_binary_path: /usr/local/bin`), whether to require pip3 (`require_pip3: true`), and the path to the roles and requirements files. +This section configures the transport, which is the method Test Kitchen uses to communicate with the instance. Here, it's using the Dokken transport, which communicates with the Docker container. ```yaml -lifecycle: - pre_converge: - - remote: | - ... +platforms: + - name: ubi9 ``` -This section defines lifecycle hooks, which are commands that run at certain points in the Test Kitchen run. Here, it's running a series of commands before the converge phase (i.e., before applying the infrastructure code). These commands install necessary packages, update system packages, and update the `ec2-user` configuration. +This section defines the platforms on which your tests will run. In this case, it's UBI 9 (Red Hat's Universal Base Image 9). ```yaml -transport: - name: ssh - max_ssh_sessions: 2 +suites: + - name: vanilla + driver: + image: <%= ENV['VANILLA_CONTAINER_IMAGE'] || "registry.access.redhat.com/ubi9/ubi:9.3-1610" %> + verifier: + input_files: + - container.vanilla.inputs.yml + - name: hardened + driver: + image: <%= ENV['HARDENED_CONTAINER_IMAGE'] || "registry1.dso.mil/ironbank/redhat/ubi/ubi9" %> + verifier: + input_files: + - container.hardened.inputs.yml ``` -This section configures the transport, which is the method Test Kitchen uses to communicate with the instance. Here, it's using SSH and allowing a maximum of 2 SSH sessions. +This section defines the test suites. Each suite represents a different configuration to test. + +- Each suite has a `name`, a `driver`, and a `verifier`. +- The `driver` section specifies the Docker image to use for the suite. It's dynamically set based on the `VANILLA_CONTAINER_IMAGE` or `HARDENED_CONTAINER_IMAGE` environment variable, with a default value if the variable is not set. +- The `verifier` section specifies files that contain input variables for the InSpec profile. The workflow of Test Kitchen involves the following steps: -1. **Create:** Test Kitchen uses the driver to create an instance of the platform. -2. **Converge:** Test Kitchen uses the provisioner to apply the infrastructure code to the instance. Before this phase, it runs the commands defined in the `pre_converge` lifecycle hook. -3. **Verify:** Test Kitchen checks if the instance is in the desired state. This is not shown in your file, but it would be configured in the `verifier` section. -4. **Destroy:** Test Kitchen uses the driver to destroy the instance after testing. This is not shown in your file, but it would be configured in the `driver` section. +1. **Create:** Test Kitchen uses the driver to create a Docker container of the platform. +2. **Converge:** Test Kitchen uses the provisioner to apply the infrastructure code to the container. In this case, no provisioning is done. +3. **Verify:** Test Kitchen checks if the container is in the desired state. This is not shown in your file, but it would be configured in the `verifier` section. +4. **Destroy:** Test Kitchen uses the driver to destroy the container after testing. This is not shown in your file, but it would be configured in the `driver` section. + +The `transport` is used in all these steps to communicate with the container. + +## Environment Variables in `kitchen.container.yml` + +The `kitchen.container.yml` file uses the following environment variables to select the containers used during its `hardened` and `vanilla` testing runs. You can test any container using these environment variables, even though standard defaults are set. -The `transport` is used in all these steps to communicate with the instance. +- `VANILLA_CONTAINER_IMAGE`: This variable specifies the Docker container image considered 'not hardened'. + - default: `registry.access.redhat.com/ubi9/ubi:9.3-1610` +- `HARDENED_CONTAINER_IMAGE`: This variable specifies the Docker container image considered 'hardened'. + - default: `registry1.dso.mil/ironbank/redhat/ubi/ubi9` diff --git a/src/courses/profile-dev-test/23.md b/src/courses/profile-dev-test/23.md deleted file mode 100644 index 6abc9ae40..000000000 --- a/src/courses/profile-dev-test/23.md +++ /dev/null @@ -1,120 +0,0 @@ ---- -order: 23 -next: 24.md -title: Test Kitchen - `kitchen.container.yml` -author: Aaron Lippold ---- - -## Understanding the [`kitchen.container.yml`](./kitchen.container.yml) - -The `kitchen.container.yml` file orchestrates our container-based test suite. It defines two types of containers: hardened and vanilla, and specifies the InSpec tests to run against them. It also configures the generation and storage of test reports. - -Unlike other test suites, the container suite skips the 'provisioner' stage for the vanilla and hardened targets. Instead, during the create stage, it simply downloads and starts the specified images. This is due to the use of the [dummy Test Kitchen driver](https://github.com/test-kitchen/test-kitchen/blob/main/lib/kitchen/driver/dummy.rb), which is ideal for interacting with pre-configured or immutable targets like containers. - -This approach allows for the evaluation of existing containers, even those created by other workflows. It can be leveraged to build a generalized workflow for validating any container against our Benchmark requirements, providing a comprehensive assessment of its security posture. - -## Example `kitchen.container.yml` file - -```yaml ---- -# see: https://kitchen.ci/docs/drivers/dokken/ - -provisioner: - name: dummy - -driver: - name: dokken - pull_platform_image: false - -transport: - name: dokken - -platforms: - - name: ubi8 - -suites: - - name: vanilla - driver: - image: <%= ENV['VANILLA_CONTAINER_IMAGE'] || "registry.access.redhat.com/ubi8/ubi:8.9-1028" %> - verifier: - input_files: - - container.vanilla.inputs.yml - - name: hardened - driver: - image: <%= ENV['HARDENED_CONTAINER_IMAGE'] || "registry1.dso.mil/ironbank/redhat/ubi/ubi8" %> - verifier: - input_files: - - container.hardened.inputs.yml - # creds_file: './creds.json' -``` - -# Breakdown of the `kitchen.container.yml` file - -```yaml -provisioner: - name: dummy -``` - -This section configures the provisioner, which is the tool that brings your system to the desired state. Here, it's using a dummy provisioner, which means no provisioning will be done. - -```yaml -driver: - name: dokken - pull_platform_image: false -``` - -This section configures the driver, which is responsible for creating and managing the instances. Here, it's set to use the Dokken driver, which is designed for running tests in Docker containers. The `pull_platform_image: false` option means that it won't automatically pull the Docker image for the platform; it will use the image specified in the suite. - -```yaml -transport: - name: dokken -``` - -This section configures the transport, which is the method Test Kitchen uses to communicate with the instance. Here, it's using the Dokken transport, which communicates with the Docker container. - -```yaml -platforms: - - name: ubi8 -``` - -This section defines the platforms on which your tests will run. In this case, it's UBI 8 (Red Hat's Universal Base Image 8). - -```yaml -suites: - - name: vanilla - driver: - image: <%= ENV['VANILLA_CONTAINER_IMAGE'] || "registry.access.redhat.com/ubi8/ubi:8.9-1028" %> - verifier: - input_files: - - container.vanilla.inputs.yml - - name: hardened - driver: - image: <%= ENV['HARDENED_CONTAINER_IMAGE'] || "registry1.dso.mil/ironbank/redhat/ubi/ubi8" %> - verifier: - input_files: - - container.hardened.inputs.yml -``` - -This section defines the test suites. Each suite represents a different configuration to test. - -- Each suite has a `name`, a `driver`, and a `verifier`. -- The `driver` section specifies the Docker image to use for the suite. It's dynamically set based on the `VANILLA_CONTAINER_IMAGE` or `HARDENED_CONTAINER_IMAGE` environment variable, with a default value if the variable is not set. -- The `verifier` section specifies files that contain input variables for the InSpec profile. - -The workflow of Test Kitchen involves the following steps: - -1. **Create:** Test Kitchen uses the driver to create a Docker container of the platform. -2. **Converge:** Test Kitchen uses the provisioner to apply the infrastructure code to the container. In this case, no provisioning is done. -3. **Verify:** Test Kitchen checks if the container is in the desired state. This is not shown in your file, but it would be configured in the `verifier` section. -4. **Destroy:** Test Kitchen uses the driver to destroy the container after testing. This is not shown in your file, but it would be configured in the `driver` section. - -The `transport` is used in all these steps to communicate with the container. - -## Environment Variables in `kitchen.container.yml` - -The `kitchen.container.yml` file uses the following environment variables to select the containers used during its `hardened` and `vanilla` testing runs. You can test any container using these environment variables, even though standard defaults are set. - -- `VANILLA_CONTAINER_IMAGE`: This variable specifies the Docker container image considered 'not hardened'. - - default: `registry.access.redhat.com/ubi8/ubi:8.9-1028` -- `HARDENED_CONTAINER_IMAGE`: This variable specifies the Docker container image considered 'hardened'. - - default: `registry1.dso.mil/ironbank/redhat/ubi/ubi8` From 6251f30dddca644bace0db9f970620ec807702ab Mon Sep 17 00:00:00 2001 From: Amndeep Singh Mann Date: Thu, 12 Dec 2024 22:26:31 -0800 Subject: [PATCH 21/27] pg 23 - github Signed-off-by: Amndeep Singh Mann --- src/courses/profile-dev-test/21.md | 4 ++-- src/courses/profile-dev-test/{24.md => 23.md} | 20 +++++++------------ 2 files changed, 9 insertions(+), 15 deletions(-) rename src/courses/profile-dev-test/{24.md => 23.md} (57%) diff --git a/src/courses/profile-dev-test/21.md b/src/courses/profile-dev-test/21.md index 2ad522407..94fb6c7d7 100644 --- a/src/courses/profile-dev-test/21.md +++ b/src/courses/profile-dev-test/21.md @@ -1,6 +1,6 @@ --- -order: 22 -next: 23.md +order: 21 +next: 22.md title: Test Kitchen - `kitchen.ec2.yml` File author: Aaron Lippold --- diff --git a/src/courses/profile-dev-test/24.md b/src/courses/profile-dev-test/23.md similarity index 57% rename from src/courses/profile-dev-test/24.md rename to src/courses/profile-dev-test/23.md index 42e35d0a8..9c244a1b8 100644 --- a/src/courses/profile-dev-test/24.md +++ b/src/courses/profile-dev-test/23.md @@ -1,7 +1,7 @@ --- -order: 24 -next: 25.md -title: GitHub Actions +order: 23 +next: 24.md +title: 23. GitHub Actions author: Aaron Lippold --- @@ -9,11 +9,11 @@ author: Aaron Lippold Our profile utilizes GitHub Actions as its primary CI/CD process. The Actions are separated by general business or process functions, allowing for a clear distinction between the workflow stages that we are testing. -### [`lint-profile.yml`](.github/workflows/lint-profile.yml) +### [`lint-profile.yml`](https://github.com/mitre/redhat-enterprise-linux-9-stig-baseline/blob/main/.github/workflows/lint-profile.yml) This action checks out the repository, installs Ruby and InSpec, then runs `bundle exec inspec check .` to validate the structure and syntax of the InSpec profile and its Ruby code. -### [`verify-ec2.yml`](.github/workflows/verify-ec2.yml) +### [`verify-ec2.yml`](https://github.com/mitre/redhat-enterprise-linux-9-stig-baseline/blob/main/.github/workflows/verify-ec2.yml) This action performs the following steps: @@ -27,12 +27,6 @@ This action performs the following steps: 8. Uploads the results to our Heimdall Demo server. 9. Determines the success or failure of the test run based on the validation of the test suite results against the `threshold.yml` files for each test suite (`hardened` and `vanilla`). -### [`verify-container.yml`](.github/workflows/verify-container.yml) +### [`verify-container.yml`](https://github.com/mitre/redhat-enterprise-linux-9-stig-baseline/blob/main/.github/workflows/verify-container.yml) -This action performs similar steps to `verify-ec2.yml`, with some differences: - -1. Configures access to the required container registries - Platform One and Red Hat. - -### [`verify-vagrant.yml.example`](.github/workflows/verify-vagrant.yml.example) - -This action is similar to the `verify-ec2` workflow, but instead of using a remote AWS EC2 instance in a VPC, it uses a local Vagrant virtual machine as the test target. The user can configure whether to upload the results to our Heimdall Demo server or not by modifying the GitHub Action. +This action performs similar steps to `verify-ec2.yml`, with a key additional step of configuring access to the required container registries - Platform One and Red Hat. From 592361aa5b3a02c977939ca51bfe0a9d7dbb7cd3 Mon Sep 17 00:00:00 2001 From: Amndeep Singh Mann Date: Thu, 12 Dec 2024 22:37:14 -0800 Subject: [PATCH 22/27] pg 24 - tips Signed-off-by: Amndeep Singh Mann --- src/courses/profile-dev-test/21.md | 2 +- src/courses/profile-dev-test/{25.md => 24.md} | 22 +++++++++++-------- 2 files changed, 14 insertions(+), 10 deletions(-) rename src/courses/profile-dev-test/{25.md => 24.md} (66%) diff --git a/src/courses/profile-dev-test/21.md b/src/courses/profile-dev-test/21.md index 94fb6c7d7..b3ae927c3 100644 --- a/src/courses/profile-dev-test/21.md +++ b/src/courses/profile-dev-test/21.md @@ -1,7 +1,7 @@ --- order: 21 next: 22.md -title: Test Kitchen - `kitchen.ec2.yml` File +title: 21. Test Kitchen - `kitchen.ec2.yml` File author: Aaron Lippold --- diff --git a/src/courses/profile-dev-test/25.md b/src/courses/profile-dev-test/24.md similarity index 66% rename from src/courses/profile-dev-test/25.md rename to src/courses/profile-dev-test/24.md index 728b4f02d..60abdd1a6 100644 --- a/src/courses/profile-dev-test/25.md +++ b/src/courses/profile-dev-test/24.md @@ -1,7 +1,7 @@ --- -order: 25 -next: 26.md -title: Tips, Tricks, and Troubleshooting +order: 24 +next: 25.md +title: 24. Tips, Tricks, and Troubleshooting shortTitle: Tips & Troubleshooting author: Aaron Lippold --- @@ -28,11 +28,15 @@ Test Kitchen stores the current host details of your provisioned test targets in #### Restoring Access to a Halted or Restarted Test Target -If your test target reboots or updates its network information, you don't need to execute bundle exec kitchen destroy. Instead, update the corresponding .kitchen/#{suite}-#{target}.yml file with the updated information. This will ensure that your kitchen login, kitchen validate, and other kitchen commands function correctly, as they'll be connecting to the correct location instead of using outdated data. +If your test target reboots or updates its network information, you don't need to execute `bundle exec kitchen destroy`. Instead, update the corresponding `.kitchen/#{suite}-#{target}.yml` file with the updated information. This will ensure that your `kitchen login`, `kitchen validate`, and other kitchen commands function correctly, as they'll be connecting to the correct location instead of using outdated data. #### AWS Console and EC2 Oddities -Since we're using the free-tier for our AWS testing resources instead of a dedicated host, your test targets might shut down or 'reboot in the background' if you stop interacting with them, halt them, put them in a stop state, or leave them overnight. To regain access, edit the .kitchen/#{suite}-#{target}.yml file. As mentioned above, there's no need to recreate your testing targets if you can simply point Test Kitchen to the correct IP address. +Since we're using the free-tier for our AWS testing resources instead of a dedicated host, your test targets might shut down or reboot in the background if you stop interacting with them, halt them, put them in a stop state, or leave them unattended overnight. To regain access, edit the `.kitchen/#{suite}-#{target}.yml` file. As mentioned above, there's no need to recreate your testing targets if you can simply point Test Kitchen to the correct IP address. + +:::warning Auto-generated, sensitive files +Since the `.kitchen/` directory is automatically generated by Test Kitchen, you need to be careful not to accidentally mess up its internal workings when editing it by hand as suggested above. Additionally, be sure not to place this directory underneath version control since you could unintentionally leak sensitive information such as your ip addresses and credentials! +::: ## InSpec / Ruby @@ -46,13 +50,13 @@ When developing InSpec controls, it's beneficial to use the `kitchen-test` suite 2. Then, insert `binding.pry` at the point in your code where you want to start debugging. 3. When you run your tests, execution will stop at the `binding.pry` line, and you can inspect variables, step through the code, and more. -***!Pro Tip!*** - -- Remember to remove or comment out the `binding.pry` lines when you're done debugging or you won't have a good 'linting' down the road. +::: tip Linter +Remember to remove or comment out the `binding.pry` lines when you're done debugging or you won't have a good 'linting' down the road. +::: ### Streamlining Your Testing with `inspec shell` -The `inspec shell` command allows you to test your full control update on your test target directly. To do this, you'll need to retrieve the IP address and SSH PEM key for your target instance from the Test Kitchen `.kitchen` directory. For more details on this, refer to the [Finding Your Test Target Login Details](#311-locating-test-target-login-details) section. +The `inspec shell` command allows you to test your full control update on your test target directly. To do this, you'll need to retrieve the IP address and SSH PEM key for your target instance from the Test Kitchen `.kitchen` directory. For more details on this, refer to the [Locating Test Target Login Details](#locating-test-target-login-details) section. Once you have your IP address and SSH PEM key (for AWS target instances), or the container ID (for Docker test instances), you can use the following commands: From 11d1cd193f64a277e6907811e22cf0c9d38a3848 Mon Sep 17 00:00:00 2001 From: Amndeep Singh Mann Date: Thu, 12 Dec 2024 22:47:34 -0800 Subject: [PATCH 23/27] last few Signed-off-by: Amndeep Singh Mann --- src/courses/profile-dev-test/24.md | 1 - src/courses/profile-dev-test/25.md | 30 ++ src/courses/profile-dev-test/26.md | 42 +- src/courses/profile-dev-test/27.md | 22 - .../kitchen-workflow-dark.svg | 481 ------------------ 5 files changed, 47 insertions(+), 529 deletions(-) create mode 100644 src/courses/profile-dev-test/25.md delete mode 100644 src/courses/profile-dev-test/27.md delete mode 100644 src/courses/profile-dev-test/kitchen-workflow-dark.svg diff --git a/src/courses/profile-dev-test/24.md b/src/courses/profile-dev-test/24.md index 60abdd1a6..55cf4a2c5 100644 --- a/src/courses/profile-dev-test/24.md +++ b/src/courses/profile-dev-test/24.md @@ -2,7 +2,6 @@ order: 24 next: 25.md title: 24. Tips, Tricks, and Troubleshooting -shortTitle: Tips & Troubleshooting author: Aaron Lippold --- diff --git a/src/courses/profile-dev-test/25.md b/src/courses/profile-dev-test/25.md new file mode 100644 index 000000000..d04297ed4 --- /dev/null +++ b/src/courses/profile-dev-test/25.md @@ -0,0 +1,30 @@ +--- +order: 25 +next: 26.md +title: 25. Background & Definitions +author: Aaron Lippold +--- + +## Background and Definitions + +### Background + +#### Evolution of STIGs and Security Benchmarks + +The Department of Defense (DOD) has continually updated its databases that track rules and Security Technical Implementation Guides (STIGs) that house those rules. + +Initially, the system was known as the Vulnerability Management System (VMS). + +In the STIGs, you might come across data elements that are remnants from these iterations. These include `Group Title` (gid or gtitle), `Vulnerability ID` (VulnID), `Rule ID` (rule_id), `STIG ID` (stig_id), and others. + +A significant change was the shift from using `STIG ID` to `Rule ID` in many security scanning tools. This change occurred because the Vulnerability Management System used the STIG_ID as the primary index for the requirements in each Benchmark in VMS. + +When DISA updated the Vendor STIG Processes and replaced the VMS, they decided to migrate the primary ID from the STIG ID to the Rule ID, tracking changes in the Rules as described above. + +Examples of tools that still use either fully or in part the 'STIG ID' instead of the 'Rule ID' as a primary index are: the DISA STIG Viewer, Nessus Audit Scans, and Open SCAP client. + +While these elements might seem confusing, understanding their historical context is essential. + +In our modern profiles, some data from the XCCDF Benchmarks still exist in the document but are not used or rendered in the modern InSpec Profiles. However, in some of the older profiles, you may see many of these data elements as `tags` in the profile. The intention was to ensure easy and lossless conversion between the XCCDF Benchmark and OHDF Profile. + +It was later realized that since the structure of these data elements was 'static', they could be easily reintroduced when converting back to an XCCDF Benchmark. Therefore, rendering them in the profile was deemed unnecessary. diff --git a/src/courses/profile-dev-test/26.md b/src/courses/profile-dev-test/26.md index 48ee12ecc..3cf3cca0f 100644 --- a/src/courses/profile-dev-test/26.md +++ b/src/courses/profile-dev-test/26.md @@ -1,30 +1,22 @@ --- order: 26 -next: 27.md -title: Background & Definitions +title: 26. Terms & Definitions author: Aaron Lippold --- -## Background and Definitions - -### Background - -#### Evolution of STIGs and Security Benchmarks - -The Department of Defense (DOD) has continually updated its databases that track rules and Security Technical Implementation Guides (STIGs) that house those rules. - -Initially, the system was known as the Vulnerability Management System (VMS). - -In the STIGs, you might come across data elements that are remnants from these iterations. These include `Group Title` (gid or gtitle), `Vulnerability ID` (VulnID), `Rule ID` (rule_id), `STIG ID` (stig_id), and others. - -A significant change was the shift from using `STIG ID` to `Rule ID` in many security scanning tools. This change occurred because the Vulnerability Management System used the STIG_ID as the primary index for the requirements in each Benchmark in VMS. - -However, when DISA updated the Vendor STIG Processes and replaced the VMS, they decided to migrate the primary ID from the STIG ID to the Rule ID, tracking changes in the Rules as described above. - -Examples of tools that still use either fully or in part the 'STIG ID' vs the 'Rule ID' as a primary index are: the DISA STIG Viewer, Nessus Audit Scans, and Open SCAP client. - -While these elements might seem confusing, understanding their historical context is essential. - -In our modern profiles, some data from the XCCDF Benchmarks still exist in the document but are not used or rendered in the modern InSpec Profiles. However, in some of the older profiles, you may see many of these data elements as `tags` in the profile. The intention was to ensure easy and lossless conversion between XCCDF Benchmark and HDF Profile. - -It was later realized that since the structure of these data elements was 'static', they could be easily reintroduced when converting back to an XCCDF Benchmark. Therefore, rendering them in the profile was deemed unnecessary. +## Terms & Definitions + +- **Baseline**: This refers to a set of relevant security controls, such as NIST 800-53 controls or Center for Internet Security Controls. These controls offer high-level security best practices, grouped into common areas of concern. +- **Benchmark**: This is a set of security controls tailored to a specific type of application or product. These controls are typically categorized into 'high', 'medium', and 'low' levels based on Confidentiality, Integrity, and Availability (C.I.A). +- **[Common Correlation Identifier](https://public.cyber.mil/stigs/cci/) (CCI)**: The Control Correlation Identifier (CCI) provides a standard identifier and description for each of the singular, actionable statements that comprise an IA control or IA best practice. For example: 'CCI-000366'. +- **Group Title (gtitle)**: This is essentially the SRG ID but is a holdover data value from the old Vulnerability Management System. For example: 'SRG-OS-000480-GPOS-00227'. +- **Major Version Update**: These are updates that occur when a software vendor releases a new major version of their product's STIG, e.g., Red Hat releasing version 9 of Red Hat Enterprise Linux or Microsoft releasing a new major version of Windows. +- **Patch Update**: These are regular updates that address missing corner cases of testing for one or more benchmark requirements, or improvements to the InSpec code for a requirement. These updates result in a new patch release of the benchmark, e.g., `v1.12.4` to `v1.12.5`. +- **Profile**: This is a set of tests representing a STIG or a CIS Benchmark. These tests automate the validation of a system against that STIG or CIS Benchmark. +- **Release Update**: These are updates that occur when the STIG Benchmark owner releases an updated version of the STIG, e.g., Red Hat Enterprise Linux V1R12 to V1R13. +- **Rule ID (rid)**: The Rule ID has two parts separated by the `r` in the string - ('SV-230221) and (r858734_rule)'. The first part remains unique within the major version of a Benchmark document, while the latter part of the string is updated each time the 'Rule' is updated 'release to release' of the Benchmark. For example: 'SV-230221r858734_rule'. +- **Security Requirements Guide (SRG)**: SRG documents provide generalized security guidance in XCCDF format that applies to a 'class' of software products such as 'web server', 'operating systems', 'application servers' or 'databases'. You can find an archive of these at the DISA STIG [Document Library](https://public.cyber.mil/stigs/downloads/). +- **Security Technical Implementation Guide (STIG)**: This is a set of specific technical actions required to establish a certain security posture for a software product. It is based on a desired Security Requirements Guide that applies to the product's software class and function, such as operating system, web server, database, etc. You can find an archive of these at the DISA STIG [Document Library](https://public.cyber.mil/stigs/downloads/). +- **SRG_ID**: This is the unique identifier of the SRG requirement. These indexes, like the STIG Rule IDs, also show their parent-child relationship. For example: 'SRG-OS-000480-GPOS-00227'. +- **STIG ID (stig_id)**: Many testing tools and testing results tools use this ID - vs the Rule ID - to display each of the individual results of a Benchmark validation run. For example: 'RHEL-08-010000'. Examples include: DISA STIG Viewer, Nessus Audit Scans and the Open SCAP client. +- **XCCDF Benchmark (XCCDF or XCCDF Benchmark)**: XCCDF (Extensible Configuration Checklist Description Format) is a standard developed by NIST and DOD to provide a machine-readable XML format for creating security guidance documents and security technical implementation guides. You can find an archive of these at the DISA STIG [Document Library](https://public.cyber.mil/stigs/downloads/). diff --git a/src/courses/profile-dev-test/27.md b/src/courses/profile-dev-test/27.md deleted file mode 100644 index 496c4d319..000000000 --- a/src/courses/profile-dev-test/27.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -order: 27 -title: Terms & Definitions -author: Aaron Lippold ---- - -## Terms & Definitions - -- **Baseline**: This refers to a set of relevant security controls, such as NIST 800-53 controls or Center for Internet Security Controls. These controls offer high-level security best practices, grouped into common areas of concern. -- **Benchmark**: This is a set of security controls tailored to a specific type of application or product. These controls are typically categorized into 'high', 'medium', and 'low' levels based on Confidentiality, Integrity, and Availability (C.I.A). -- **[Common Correlation Identifier](https://public.cyber.mil/stigs/cci/) (CCI)**: The Control Correlation Identifier (CCI) provides a standard identifier and description for each of the singular, actionable statements that comprise an IA control or IA best practice. For example: 'CCI-000366'. -- **Group Title (gtitle)**: This is essentially the SRG ID but is a holdover data value from the old Vulnerability Management System. For example: 'SRG-OS-000480-GPOS-00227'. -- **Major Version Update**: These are updates that occur when a software vendor releases a new major version of their product's STIG, e.g., RedHat releasing version 9 of Red Hat Enterprise Linux or Microsoft releasing a new major version of Windows. -- **Patch Update**: These are regular updates that address missing corner cases of testing for one or more benchmark requirements, or improvements to the InSpec code for a requirement. These updates result in a new patch release of the benchmark, e.g., `v1.12.4` to `v1.12.5`. -- **Profile**: This is a set of tests representing a STIG or a CIS Benchmark. These tests automate the validation of a system against that STIG or CIS Benchmark. -- **Release Update**: These are updates that occur when the STIG Benchmark owner releases an updated version of the STIG, e.g., Red Hat Enterprise Linux V1R12 to V1R13. -- **Rule ID (rid)**: The Rule ID has two parts separated by the `r` in the string - ('SV-230221) and (r858734_rule)'. The first part remains unique within the major version of a Benchmark document, while the latter part of the string is updated each time the 'Rule' is updated 'release to release' of the Benchmark. For example: 'SV-230221r858734_rule'. -- **Security Requirements Guide (SRG)**: SRG documents provide generalized security guidance in XCCDF format that applies to a 'class' of software products such as 'web server', 'operating systems', 'application servers' or 'databases'. You can find an archive of these at the DISA STIG [Document Library](https://public.cyber.mil/stigs/downloads/). -- **Security Technical Implementation Guide (STIG)**: This is a set of specific technical actions required to establish a certain security posture for a software product. It is based on a desired Security Requirements Guide that applies to the product's software class and function, such as operating system, web server, database, etc. You can find an archive of these at the DISA STIG [Document Library](https://public.cyber.mil/stigs/downloads/). -- **SRG_ID**: This is the unique identifier of the SRG requirement. These indexes, like the STIG Rule IDs, also show their parent-child relationship. For example: 'SRG-OS-000480-GPOS-00227'. -- **STIG ID (stig_id)**: Many testing tools and testing results tools use this ID - vs the Rule ID - to display each of the individual results of a Benchmark validation run. For example: 'RHEL-08-010000'. Examples include: DISA STIG Viewer, Nessus Audit Scans and the Open SCAP client. -- **XCCDF Benchmark (XCCDF or XCCDF Benchmark)**: XCCDF (Extensible Configuration Checklist Description Format) is a standard developed by NIST and DOD to provide a machine-readable XML format for creating security guidance documents and security technical implementation guides. You can find an archive of these at the DISA STIG [Document Library](https://public.cyber.mil/stigs/downloads/). diff --git a/src/courses/profile-dev-test/kitchen-workflow-dark.svg b/src/courses/profile-dev-test/kitchen-workflow-dark.svg deleted file mode 100644 index 7a552a96f..000000000 --- a/src/courses/profile-dev-test/kitchen-workflow-dark.svg +++ /dev/null @@ -1,481 +0,0 @@ -1
Setup
Setup
Checkout Repo
Checkout Repo
Install Tools
Install Tools
Setup Runner
Setup Runner
Configure
Configure
Setup Vanilla Instance
Setup Vanilla Instance
Setup Hardened Instance
Setup Hardened Instance
Run Test Suite
Run Test Suite
Run Tests on Vanilla
Run Tests on Vanilla
Run Tests on Hardened
Run Tests on Hardened
Record Results
Record Results
Save Tests in Pipeline
Save Tests in Pipeline
Upload Tests to Heimdall Server
Upload Tests to Heimdall Server
Validate Aginst Threshold
Validate Aginst Threshold
Validate the 'vanilla' threshold
Validate the 'vanilla' threshold
Validate the 'hardened' threshold
Validate the 'hardened' threshold
Pass/Fail the Run
Pass/Fail the Run
Threshold Met
Threshold Met
1
Threshold Not Met
Threshold Not Met
Test Kitchen Workflow - - - - - - - - - - - - 1 - - - - - - - - - - -
-
- Setup -
-
-
- - - Setup - - -
-
- - - - - - - - - - - - - - -
-
- Checkout Repo -
-
-
- - - Checkout Repo - - -
-
- - - - - - - - - - - - - - -
-
- Install Tools -
-
-
- - - Install Tools - - -
-
- - - - - - - - - - - - - - -
-
- Setup Runner -
-
-
- - - Setup Runner - - -
-
- - - - -
-
- Configure -
-
-
- - - Configure - - -
-
- - - - - - - - - - - - - - -
-
- Setup Vanilla Instance -
-
-
- - - Setup Vanilla Instance - - -
-
- - - - - - - - - - - - - - -
-
- Setup Hardened Instance -
-
-
- - - Setup Hardened Instance - - -
-
- - - - -
-
- Run Test Suite -
-
-
- - - Run Test Suite - - -
-
- - - - - - - - - - - - - - -
-
- Run Tests on Vanilla -
-
-
- - - Run Tests on Vanilla - - -
-
- - - - - - - - - - - - - - -
-
- Run Tests on Hardened -
-
-
- - - Run Tests on Hardened - - -
-
- - - - -
-
- Record Results -
-
-
- - - Record Results - - -
-
- - - - - - - - - - - - - - -
-
- Save Tests in Pipeline -
-
-
- - - Save Tests in Pipeline - - -
-
- - - - - - - - - - - - - - -
-
- Upload Tests to Heimdall Server -
-
-
- - - Upload Tests to Heimdall Server - - -
-
- - - - -
-
- Validate Aginst Threshold -
-
-
- - - Validate Aginst Threshold - - -
-
- - - - - - - - - - - - - - -
-
- Validate the 'vanilla' threshold -
-
-
- - - Validate the 'vanilla' threshold - - -
-
- - - - - - - - - - - - - - -
-
- Validate the 'hardened' threshold -
-
-
- - - Validate the 'hardened' threshold - - -
-
- - - - -
-
- Pass/Fail the Run -
-
-
- - - Pass/Fail the Run - - -
-
- - - - - - - - - - - - - - -
-
- Threshold Met -
-
-
- - - Threshold Met - - -
-
- - - - - - - - - - - - 1 - - - - -
-
- Threshold Not Met -
-
-
- - - Threshold Not Met - - -
-
- - Test Kitchen Workflow - - -
\ No newline at end of file From dd54750a5837b743cc55b8b82703993d68d66e4a Mon Sep 17 00:00:00 2001 From: Will Date: Thu, 12 Dec 2024 23:56:22 -0800 Subject: [PATCH 24/27] module --> class, fixing weird indentation on code blocks Signed-off-by: Will --- src/courses/profile-dev-test/05.md | 26 +++++++++++++------------- src/courses/profile-dev-test/README.md | 6 +++--- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/courses/profile-dev-test/05.md b/src/courses/profile-dev-test/05.md index f1bbfc018..a8bf539d3 100644 --- a/src/courses/profile-dev-test/05.md +++ b/src/courses/profile-dev-test/05.md @@ -28,9 +28,9 @@ This guide assumes basic familiarity with AWS. If you're new to AWS, please revi 6. (Optional) Target a specific control: - ```bash - export INSPEC_CONTROL='SV-230222' - ``` +```bash +export INSPEC_CONTROL='SV-230222' +``` ## Running Through the AWS Test Suite @@ -40,24 +40,24 @@ This guide assumes basic familiarity with AWS. If you're new to AWS, please revi 7. List the kitchen instances: ```bash - bundle exec kitchen list +bundle exec kitchen list ``` You should see something like this: ```shell - Instance Driver Provisioner Verifier Transport Last Action Last Error - vanilla-rhel-8 Ec2 AnsiblePlaybook Inspec Ssh Verified None - hardened-rhel-8 Ec2 AnsiblePlaybook Inspec Ssh Verified None +Instance Driver Provisioner Verifier Transport Last Action Last Error +vanilla-rhel-8 Ec2 AnsiblePlaybook Inspec Ssh Verified None +hardened-rhel-8 Ec2 AnsiblePlaybook Inspec Ssh Verified None ``` ### Key Testing Steps Explained 8. **Create** the test instance: - ```bash - bundle exec kitchen create vanilla - ``` +```bash +bundle exec kitchen create vanilla +``` Executing that line launches a fresh EC2 instance for testing: @@ -72,9 +72,9 @@ Executing that line launches a fresh EC2 instance for testing: 9. **Converge** the instance: - ```bash - bundle exec kitchen converge vanilla - ``` +```bash +bundle exec kitchen converge vanilla +``` Convergence applies the necessary configurations to prepare the system for testing: diff --git a/src/courses/profile-dev-test/README.md b/src/courses/profile-dev-test/README.md index 09db9f566..5e17a28ab 100644 --- a/src/courses/profile-dev-test/README.md +++ b/src/courses/profile-dev-test/README.md @@ -10,7 +10,7 @@ author: Aaron Lippold ## Learning Objectives -By completing this module, you will be able to: +By the end of this class, you will be able to: - Build and validate InSpec profiles using Test Kitchen - Configure local testing environments for security compliance @@ -20,7 +20,7 @@ By completing this module, you will be able to: ## Prerequisites -Before starting this module, ensure you have: +Before starting this class, ensure you have: - Basic knowledge of Ruby ([Learn Ruby Basics](https://ruby-lang.org/en/documentation/quickstart/)) - Docker or Podman installed ([Docker Installation Guide](https://docs.docker.com/get-docker/)) @@ -39,7 +39,7 @@ Before proceeding, verify you can: ## Overview -The development and testing of profiles are accomplished using a variety of tools, including Ruby, the Test Kitchen suite, InSpec compliance language, Ansible, Docker, and shell scripting (bash/zsh). To contribute with Pull Requests and fixes, you'll need to set up your local test suite by following the instructions provided below. +The development and testing of InSpec validation profiles can be accomplished using a variety of tools working in concert, including Ruby, the Test Kitchen suite, the InSpec compliance language itself, Ansible, Docker, and shell scripting (bash/zsh). To contribute with Pull Requests and fixes, you'll need to set up your local test suite by following the instructions provided below. ### Key Tools Explained From 40ad023cabecda3550d71238603851042f5f3a1d Mon Sep 17 00:00:00 2001 From: Will Date: Fri, 13 Dec 2024 00:07:22 -0800 Subject: [PATCH 25/27] typo Signed-off-by: Will --- src/courses/profile-dev-test/07.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/courses/profile-dev-test/07.md b/src/courses/profile-dev-test/07.md index b68dbfd4b..dcedf2b03 100644 --- a/src/courses/profile-dev-test/07.md +++ b/src/courses/profile-dev-test/07.md @@ -81,7 +81,7 @@ The choice between micro and massive PRs can significantly impact the workflows - **Patch and Release Updates:** These updates typically involve minor changes or additions, which can be easily managed with either micro or massive PRs. The choice depends on your team's preference for review speed and context switching. -- **Major Version or Large Jump Release Updates:** These updates require a thorough review of every single control and requirement. They also necessitate extensive testing, both automated (via the CI/CD testing matrix) and manual. In this scenario, the overhead of managing multiple micro or mini PRs can be substantial. However, the benefit is that it allows for more granitary control and review of changes. It's also easier to isolate and fix issues that arise during testing. +- **Major Version or Large Jump Release Updates:** These updates require a thorough review of every single control and requirement. They also necessitate extensive testing, both automated (via the CI/CD testing matrix) and manual. In this scenario, the overhead of managing multiple micro or mini PRs can be substantial. However, the benefit is that it allows for more granular control and review of changes. It's also easier to isolate and fix issues that arise during testing. ## Practice Exercise From 4e626b7fb5966486a38dc3a7dfd18570a91683df Mon Sep 17 00:00:00 2001 From: Amndeep Singh Mann Date: Sat, 14 Dec 2024 12:09:16 -0500 Subject: [PATCH 26/27] Update src/courses/advanced/03.md Signed-off-by: Amndeep Singh Mann --- src/courses/advanced/03.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/courses/advanced/03.md b/src/courses/advanced/03.md index f0b4d1741..2cb85695e 100644 --- a/src/courses/advanced/03.md +++ b/src/courses/advanced/03.md @@ -100,7 +100,7 @@ inputs: - admin ``` -You should have an inputs file in your profile, at `my_nginx/inputs.yml`. It should say the following: +You should have an inputs file in your profile at `my_nginx/inputs.yml`. It should say the following: ```yaml admin_users: From b0842f105a7e988ec6713f16d201260e5f17ea57 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 14 Dec 2024 17:09:53 +0000 Subject: [PATCH 27/27] Bump the vuepress group across 1 directory with 5 updates Bumps the vuepress group with 5 updates in the / directory: | Package | From | To | | --- | --- | --- | | [@vuepress/bundler-vite](https://github.com/vuepress/core) | `2.0.0-rc.18` | `2.0.0-rc.19` | | [@vuepress/plugin-markdown-image](https://github.com/vuepress/ecosystem/tree/HEAD/plugins/plugin-markdown-image) | `2.0.0-rc.62` | `2.0.0-rc.66` | | [@vuepress/plugin-markdown-tab](https://github.com/vuepress/ecosystem/tree/HEAD/plugins/markdown/plugin-markdown-tab) | `2.0.0-rc.62` | `2.0.0-rc.66` | | [vuepress](https://github.com/vuejs/vuepress/tree/HEAD/packages/vuepress) | `2.0.0-rc.18` | `2.0.0-rc.19` | | [vuepress-theme-hope](https://github.com/vuepress-theme-hope/vuepress-theme-hope/tree/HEAD/packages/theme) | `2.0.0-rc.59` | `2.0.0-rc.64` | Updates `@vuepress/bundler-vite` from 2.0.0-rc.18 to 2.0.0-rc.19 - [Release notes](https://github.com/vuepress/core/releases) - [Changelog](https://github.com/vuepress/core/blob/main/CHANGELOG.md) - [Commits](https://github.com/vuepress/core/compare/v2.0.0-rc.18...v2.0.0-rc.19) Updates `@vuepress/plugin-markdown-image` from 2.0.0-rc.62 to 2.0.0-rc.66 - [Release notes](https://github.com/vuepress/ecosystem/releases) - [Commits](https://github.com/vuepress/ecosystem/commits/v2.0.0-rc.66/plugins/plugin-markdown-image) Updates `@vuepress/plugin-markdown-tab` from 2.0.0-rc.62 to 2.0.0-rc.66 - [Release notes](https://github.com/vuepress/ecosystem/releases) - [Changelog](https://github.com/vuepress/ecosystem/blob/main/plugins/markdown/plugin-markdown-tab/CHANGELOG.md) - [Commits](https://github.com/vuepress/ecosystem/commits/v2.0.0-rc.66/plugins/markdown/plugin-markdown-tab) Updates `vuepress` from 2.0.0-rc.18 to 2.0.0-rc.19 - [Release notes](https://github.com/vuejs/vuepress/releases) - [Changelog](https://github.com/vuejs/vuepress/blob/master/CHANGELOG.md) - [Commits](https://github.com/vuejs/vuepress/commits/HEAD/packages/vuepress) Updates `vuepress-theme-hope` from 2.0.0-rc.59 to 2.0.0-rc.64 - [Release notes](https://github.com/vuepress-theme-hope/vuepress-theme-hope/releases) - [Changelog](https://github.com/vuepress-theme-hope/vuepress-theme-hope/blob/main/packages/theme/CHANGELOG.md) - [Commits](https://github.com/vuepress-theme-hope/vuepress-theme-hope/commits/v2.0.0-rc.64/packages/theme) --- updated-dependencies: - dependency-name: "@vuepress/bundler-vite" dependency-type: direct:development update-type: version-update:semver-patch dependency-group: vuepress - dependency-name: "@vuepress/plugin-markdown-image" dependency-type: direct:development update-type: version-update:semver-patch dependency-group: vuepress - dependency-name: "@vuepress/plugin-markdown-tab" dependency-type: direct:development update-type: version-update:semver-patch dependency-group: vuepress - dependency-name: vuepress dependency-type: direct:development update-type: version-update:semver-patch dependency-group: vuepress - dependency-name: vuepress-theme-hope dependency-type: direct:development update-type: version-update:semver-patch dependency-group: vuepress ... Signed-off-by: dependabot[bot] --- package-lock.json | 4471 +++++++++++++++++++++------------------------ package.json | 10 +- 2 files changed, 2074 insertions(+), 2407 deletions(-) diff --git a/package-lock.json b/package-lock.json index 46a67b621..bffa610fc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,17 +9,17 @@ "version": "2.0.0", "license": "Apache-2.0", "devDependencies": { - "@vuepress/bundler-vite": "2.0.0-rc.18", - "@vuepress/plugin-markdown-image": "2.0.0-rc.62", - "@vuepress/plugin-markdown-tab": "2.0.0-rc.62", + "@vuepress/bundler-vite": "2.0.0-rc.19", + "@vuepress/plugin-markdown-image": "2.0.0-rc.66", + "@vuepress/plugin-markdown-tab": "2.0.0-rc.66", "cypress": "^13.16.1", "cypress-each": "^1.14.0", "flowchart.ts": "^3.0.1", "mermaid": "^11.4.1", "start-server-and-test": "^2.0.9", "vue": "^3.5.13", - "vuepress": "2.0.0-rc.18", - "vuepress-theme-hope": "2.0.0-rc.59" + "vuepress": "2.0.0-rc.19", + "vuepress-theme-hope": "2.0.0-rc.64" } }, "node_modules/@antfu/install-pkg": { @@ -481,6 +481,22 @@ "node": ">=12" } }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.0.tgz", + "integrity": "sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@esbuild/openbsd-x64": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", @@ -597,87 +613,23 @@ "mlly": "^1.7.1" } }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "optional": true, - "peer": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, - "optional": true, - "peer": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", - "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25" - } - }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", "dev": true }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, "node_modules/@lit-labs/ssr-dom-shim": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.2.1.tgz", "integrity": "sha512-wx4aBmgeGvFmOKucFKY+8VFJSYZxs9poN3SDNQFF6lT6NrQUnHiPB2PWz2sc4ieEcAaYYzN+1uWahEeTq2aRIQ==", - "dev": true, - "license": "BSD-3-Clause" + "dev": true }, "node_modules/@lit/reactive-element": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-2.0.4.tgz", "integrity": "sha512-GFn91inaUa2oHLak8awSIigYz0cU0Payr1rcFsrkf5OJ5eSPxElyZfKh0f2p9FsTiZWXQdWGJeXZICEfXXYSXQ==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "@lit-labs/ssr-dom-shim": "^1.2.0" } @@ -687,7 +639,6 @@ "resolved": "https://registry.npmjs.org/@mdit-vue/plugin-component/-/plugin-component-2.1.3.tgz", "integrity": "sha512-9AG17beCgpEw/4ldo/M6Y/1Rh4E1bqMmr/rCkWKmCAxy9tJz3lzY7HQJanyHMJufwsb3WL5Lp7Om/aPcQTZ9SA==", "dev": true, - "license": "MIT", "dependencies": { "@types/markdown-it": "^14.1.1", "markdown-it": "^14.1.0" @@ -698,7 +649,6 @@ "resolved": "https://registry.npmjs.org/@mdit-vue/plugin-frontmatter/-/plugin-frontmatter-2.1.3.tgz", "integrity": "sha512-KxsSCUVBEmn6sJcchSTiI5v9bWaoRxe68RBYRDGcSEY1GTnfQ5gQPMIsM48P4q1luLEIWurVGGrRu7u93//LDQ==", "dev": true, - "license": "MIT", "dependencies": { "@mdit-vue/types": "2.1.0", "@types/markdown-it": "^14.1.1", @@ -711,7 +661,6 @@ "resolved": "https://registry.npmjs.org/@mdit-vue/plugin-headers/-/plugin-headers-2.1.3.tgz", "integrity": "sha512-AcL7a7LHQR3ISINhfjGJNE/bHyM0dcl6MYm1Sr//zF7ZgokPGwD/HhD7TzwmrKA9YNYCcO9P3QmF/RN9XyA6CA==", "dev": true, - "license": "MIT", "dependencies": { "@mdit-vue/shared": "2.1.3", "@mdit-vue/types": "2.1.0", @@ -724,7 +673,6 @@ "resolved": "https://registry.npmjs.org/@mdit-vue/plugin-sfc/-/plugin-sfc-2.1.3.tgz", "integrity": "sha512-Ezl0dNvQNS639Yl4siXm+cnWtQvlqHrg+u+lnau/OHpj9Xh3LVap/BSQVugKIV37eR13jXXYf3VaAOP1fXPN+w==", "dev": true, - "license": "MIT", "dependencies": { "@mdit-vue/types": "2.1.0", "@types/markdown-it": "^14.1.1", @@ -736,7 +684,6 @@ "resolved": "https://registry.npmjs.org/@mdit-vue/plugin-title/-/plugin-title-2.1.3.tgz", "integrity": "sha512-XWVOQoZqczoN97xCDrnQicmXKoqwOjIymIm9HQnRXhHnYKOgJPW1CxSGhkcOGzvDU1v0mD/adojVyyj/s6ggWw==", "dev": true, - "license": "MIT", "dependencies": { "@mdit-vue/shared": "2.1.3", "@mdit-vue/types": "2.1.0", @@ -749,7 +696,6 @@ "resolved": "https://registry.npmjs.org/@mdit-vue/plugin-toc/-/plugin-toc-2.1.3.tgz", "integrity": "sha512-41Q+iXpLHZt0zJdApVwoVt7WF6za/xUjtjEPf90Z3KLzQO01TXsv48Xp9BsrFHPcPcm8tiZ0+O1/ICJO80V/MQ==", "dev": true, - "license": "MIT", "dependencies": { "@mdit-vue/shared": "2.1.3", "@mdit-vue/types": "2.1.0", @@ -762,7 +708,6 @@ "resolved": "https://registry.npmjs.org/@mdit-vue/shared/-/shared-2.1.3.tgz", "integrity": "sha512-27YI8b0VVZsAlNwaWoaOCWbr4eL8B04HxiYk/y2ktblO/nMcOEOLt4p0RjuobvdyUyjHvGOS09RKhq7qHm1CHQ==", "dev": true, - "license": "MIT", "dependencies": { "@mdit-vue/types": "2.1.0", "@types/markdown-it": "^14.1.1", @@ -797,9 +742,9 @@ } }, "node_modules/@mdit/plugin-alert": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-alert/-/plugin-alert-0.13.1.tgz", - "integrity": "sha512-3LMYQQ3QP6TUx6zmtmuoHJScST5SVoPZlNuuF4S6PUZvJIwtlITF+eFNjDrA7UQx0PUdCgVHmwu5kYliq+BNtg==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@mdit/plugin-alert/-/plugin-alert-0.14.0.tgz", + "integrity": "sha512-a9/E6AZkCdepiseaS7VzjTPzlDVEpDXbgfspT1V0LVJ0xHiOlPNaUhB4vuRavETFyFmbmx8Lq8SvjvN6VdIz7Q==", "dev": true, "dependencies": { "@types/markdown-it": "^14.1.2" @@ -814,13 +759,12 @@ } }, "node_modules/@mdit/plugin-align": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-align/-/plugin-align-0.13.1.tgz", - "integrity": "sha512-g8je53oEpYNHEudhtB5ViSiAaiMcca+hvoGbInhLl979tWuvEosOs0oWH2X3GM4f6goTGx8gLwzA10Z5C4FxIQ==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@mdit/plugin-align/-/plugin-align-0.14.0.tgz", + "integrity": "sha512-lm7epUka2zMHh6DpU1juX7eBAZHaGk+gcMNPknLb9LnP+zgKqEQ6Dl/86z24N9h9biAnp4AoY1uFMQB5mMvPHw==", "dev": true, - "license": "MIT", "dependencies": { - "@mdit/plugin-container": "0.13.1", + "@mdit/plugin-container": "0.14.0", "@types/markdown-it": "^14.1.2" }, "engines": { @@ -836,12 +780,12 @@ } }, "node_modules/@mdit/plugin-attrs": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-attrs/-/plugin-attrs-0.13.1.tgz", - "integrity": "sha512-3saBw5W2y3T0QNbui+uk7nfD36FOoBWNQImk+pbMGpKRqunjouiYP4ZtnttT/AiieGbZBVaOqhM4e01Uyua8VA==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@mdit/plugin-attrs/-/plugin-attrs-0.14.0.tgz", + "integrity": "sha512-/SK/mDXF+Zly7HN3ps8RB83CIWKv8r9FPGxmq9DknpXhFFOMlE5UIP9l7E0ysWmlKElfoEq9hYgUY9Ieerphtg==", "dev": true, - "license": "MIT", "dependencies": { + "@mdit/helper": "0.14.0", "@types/markdown-it": "^14.1.2" }, "engines": { @@ -857,9 +801,9 @@ } }, "node_modules/@mdit/plugin-container": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-container/-/plugin-container-0.13.1.tgz", - "integrity": "sha512-mFfm7YViyLHo8uORVa9oLi9+acZZoSVdPf3WPqzC/yLZAJbF27rfJgWZ9Kylt+tyaAYng8L4DiSeVcSNUIHF1A==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@mdit/plugin-container/-/plugin-container-0.14.0.tgz", + "integrity": "sha512-sYjR9GPPkdItjGXw2m4f2iKAvKK+9egq/3wnzNnsouK1Hz0Qz8rQM1VELQLBK16PJwqStGNfTQC31BeM7gVmIg==", "dev": true, "dependencies": { "@types/markdown-it": "^14.1.2" @@ -877,35 +821,13 @@ } }, "node_modules/@mdit/plugin-demo": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-demo/-/plugin-demo-0.13.1.tgz", - "integrity": "sha512-ne36FB7jstUblatow7ed1Z3Nm0zootM7A6b+77xEw7aJnXHkM5tJLbBfS6l8WN1Ze7fWVZbP7xQkI3wRvjqrqg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/markdown-it": "^14.1.2" - }, - "peerDependencies": { - "markdown-it": "^14.1.0" - }, - "peerDependenciesMeta": { - "markdown-it": { - "optional": true - } - } - }, - "node_modules/@mdit/plugin-figure": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-figure/-/plugin-figure-0.13.1.tgz", - "integrity": "sha512-bxeUVMPAuXHYRqPzU+1ux7R3LkpyHTdavCa05rQUhzDI07N+BZDE7oOABXnnFbx6ESamzu3/FBtq9VKjoifLmw==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@mdit/plugin-demo/-/plugin-demo-0.14.0.tgz", + "integrity": "sha512-pp5XTESSmvUKpIJMyM1RFCddXjTXhgw8HKDPAMmIc2BpeBzFUBgNBA3JBULE8KiZVPJBdc2HuswQFOYwb6IQ/A==", "dev": true, - "license": "MIT", "dependencies": { "@types/markdown-it": "^14.1.2" }, - "engines": { - "node": ">= 18" - }, "peerDependencies": { "markdown-it": "^14.1.0" }, @@ -916,69 +838,10 @@ } }, "node_modules/@mdit/plugin-footnote": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-footnote/-/plugin-footnote-0.13.1.tgz", - "integrity": "sha512-46TzNvY9QXO5y6MbXlewCe+gfw3lgF2IFQCs0enaWVSgKNaGxOuecDR68SlbLPc7unJQCcs5Bb/XB4xsx0depQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/markdown-it": "^14.1.2" - }, - "engines": { - "node": ">= 18" - }, - "peerDependencies": { - "markdown-it": "^14.1.0" - } - }, - "node_modules/@mdit/plugin-img-lazyload": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-img-lazyload/-/plugin-img-lazyload-0.13.1.tgz", - "integrity": "sha512-DPzR+yabbgqHWHb8oetOj56TtZzOcn5YZjSTssoh7lY5hp/Yy7jWvlLDrSw/LiXkYEhyocUee78enhTodBEpHQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/markdown-it": "^14.1.2" - }, - "engines": { - "node": ">= 18" - }, - "peerDependencies": { - "markdown-it": "^14.1.0" - }, - "peerDependenciesMeta": { - "markdown-it": { - "optional": true - } - } - }, - "node_modules/@mdit/plugin-img-mark": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-img-mark/-/plugin-img-mark-0.13.1.tgz", - "integrity": "sha512-HOALB1nILV5vkopSKPrclkwwc5WGbpuAWxuOLTz/teOifE8E4JsbiFivcM6URMP1lZXzRBXoniQCCOUhWRis8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/markdown-it": "^14.1.2" - }, - "engines": { - "node": ">= 18" - }, - "peerDependencies": { - "markdown-it": "^14.1.0" - }, - "peerDependenciesMeta": { - "markdown-it": { - "optional": true - } - } - }, - "node_modules/@mdit/plugin-img-size": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-img-size/-/plugin-img-size-0.13.1.tgz", - "integrity": "sha512-cgihl72BNzij7GXjrqcKhl2eOqAlqWHiImOgblJPghDFNFKnnynty/Bf9nwbj8hTnhVWznFeuwawzXBfKYNbkg==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@mdit/plugin-footnote/-/plugin-footnote-0.14.0.tgz", + "integrity": "sha512-GaBn/j7TiC3tFwR0iRKyo133FvJtPQ1qo0K3NGKULWD8M4i1K2tEuA6qRKELh3DlsNKxK6G81KnQTl/87gR3rw==", "dev": true, - "license": "MIT", "dependencies": { "@types/markdown-it": "^14.1.2" }, @@ -987,20 +850,15 @@ }, "peerDependencies": { "markdown-it": "^14.1.0" - }, - "peerDependenciesMeta": { - "markdown-it": { - "optional": true - } } }, "node_modules/@mdit/plugin-include": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-include/-/plugin-include-0.13.1.tgz", - "integrity": "sha512-rWGJ3/L2Ocv+8KDNoXPb6H1f+aLqx0FzJKcNqJl+0HOAEScuyKS1GC4OxeWefVMQ87QoG/mYqoCbpDsJeiDbLQ==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@mdit/plugin-include/-/plugin-include-0.14.0.tgz", + "integrity": "sha512-Y4XXGz9lhdSEctqMdmrN4R4nJPfgPSrtTwyptiN5ArT8fx+UIJId8AYBk5ybMZBAYne2QBHI/8+2O0xrUxJzYw==", "dev": true, - "license": "MIT", "dependencies": { + "@mdit/helper": "0.14.0", "@types/markdown-it": "^14.1.2", "upath": "^2.0.1" }, @@ -1014,13 +872,13 @@ } }, "node_modules/@mdit/plugin-katex-slim": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-katex-slim/-/plugin-katex-slim-0.13.1.tgz", - "integrity": "sha512-OO4n51aLo0Igv0aICXOaTO5+ZW/jW8Lnl8u1kxs2zkFVNUqpqNHAo8l4QxtscQk5L4XhXGgaTj2ZgAv7rtH96Q==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@mdit/plugin-katex-slim/-/plugin-katex-slim-0.14.0.tgz", + "integrity": "sha512-GztODGcbbd+Glmwrin8yeR6KDESyFwxKkwe1u40XQ4vAImtOswQbAk5suoFGySiuONzGiu/4RLOKnYv5Unq3jQ==", "dev": true, - "license": "MIT", "dependencies": { - "@mdit/plugin-tex": "0.13.1", + "@mdit/helper": "0.14.0", + "@mdit/plugin-tex": "0.14.0", "@types/katex": "^0.16.7", "@types/markdown-it": "^14.1.2" }, @@ -1041,11 +899,10 @@ } }, "node_modules/@mdit/plugin-mark": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-mark/-/plugin-mark-0.13.1.tgz", - "integrity": "sha512-UV+7cSY8iQXlfnrIJ/gEpgwiL2SSVzVLtaWMOV0J4tRSsdtN8ZXnJn/gC547SxBaOLIkt+0ObSskXaCH/UzuIA==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@mdit/plugin-mark/-/plugin-mark-0.14.0.tgz", + "integrity": "sha512-NKJB92pJissct4HCDv+GK8dMF/viX5fzf6zrO9zBmgFRfdeo6CqjuVWh+Se/mPtqwhk1f2EX80YlOXorWNjXKQ==", "dev": true, - "license": "MIT", "dependencies": { "@types/markdown-it": "^14.1.2" }, @@ -1062,13 +919,12 @@ } }, "node_modules/@mdit/plugin-mathjax-slim": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-mathjax-slim/-/plugin-mathjax-slim-0.13.1.tgz", - "integrity": "sha512-ZFtKG2BtLAk1BarJZei9HP4aK0vNU7YvDb+R+nApK7MRmLQ53xHe7upu3qlfNBoOZWHXsdRmcz0G4xL3oxzlqA==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@mdit/plugin-mathjax-slim/-/plugin-mathjax-slim-0.14.0.tgz", + "integrity": "sha512-AOFHQ5wN8IDV8d96MH3w9irHNguLtWbhYajQcc+O5wGeWxDsd5KMAd4StgERETxo6XgLxr0NRC8HzxSMPrC2aw==", "dev": true, - "license": "MIT", "dependencies": { - "@mdit/plugin-tex": "0.13.1", + "@mdit/plugin-tex": "0.14.0", "@types/markdown-it": "^14.1.2", "upath": "^2.0.1" }, @@ -1089,13 +945,12 @@ } }, "node_modules/@mdit/plugin-plantuml": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-plantuml/-/plugin-plantuml-0.13.1.tgz", - "integrity": "sha512-qupMO/lG1mDYaGHSutB9AO1TsxHjmp4yFnvp3VBNNRdVh9lqWhXFv/htrnr0IGEWAmlik6zlkCvz/YrKRONV5A==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@mdit/plugin-plantuml/-/plugin-plantuml-0.14.0.tgz", + "integrity": "sha512-AZy/o6Uvjd46GWoisYLQBL37ET0T+XscI+E8nUuZGu/ihAhoZU3jxeE97WFPwBa5T3hrNd9L1XfLXTTDM2ZQWw==", "dev": true, - "license": "MIT", "dependencies": { - "@mdit/plugin-uml": "0.13.1", + "@mdit/plugin-uml": "0.14.0", "@types/markdown-it": "^14.1.2" }, "peerDependencies": { @@ -1108,11 +963,10 @@ } }, "node_modules/@mdit/plugin-spoiler": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-spoiler/-/plugin-spoiler-0.13.1.tgz", - "integrity": "sha512-6aOD+kjGavkn+Ta0Iq8AUfBG3UsKsL5e0pxi0Eng13lIEp8DrDw36W+E6fLOFtX8Te3ays6eTkTc1I5WzHO0Gw==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@mdit/plugin-spoiler/-/plugin-spoiler-0.14.0.tgz", + "integrity": "sha512-c+tSj35JygQF9gNRAcH3gk68pBpjS7zGiooz/UK+tw8GSqez2c1Z+PWvu1u4xX0O/HO3y+amu7GqTjwkfgLC7g==", "dev": true, - "license": "MIT", "dependencies": { "@types/markdown-it": "^14.1.2" }, @@ -1129,11 +983,10 @@ } }, "node_modules/@mdit/plugin-stylize": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-stylize/-/plugin-stylize-0.13.1.tgz", - "integrity": "sha512-1v+3H1nMMvXsbu6iyV1pQ7WccrRNkuHovkIAp04Vj0FtbjnKrBHlmzFZace5OaD2RcZ0fn6qRpyR+/AIMjUvtQ==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@mdit/plugin-stylize/-/plugin-stylize-0.14.0.tgz", + "integrity": "sha512-oJFR+6JqWNnEjFsSO8FsMS92MNVzEaI+Re/3MX6OerJ7/ytdU8EkdgU8hcNcAGeT437SIKZsH9pRnxBupx0J7w==", "dev": true, - "license": "MIT", "dependencies": { "@types/markdown-it": "^14.1.2" }, @@ -1150,12 +1003,12 @@ } }, "node_modules/@mdit/plugin-sub": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-sub/-/plugin-sub-0.13.1.tgz", - "integrity": "sha512-2rIvEl6pXUoXIm3JMO5ZOQ+vWIeFXmLkqxcmTZB2yOIfhYdLwIcSyquRwtI2AX8zCuvaTdiQ/aypvIE4tDoURw==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@mdit/plugin-sub/-/plugin-sub-0.14.0.tgz", + "integrity": "sha512-wva0pmw67t1aNZR7I+1GUyaWigJp+cGcPFvuwYviUuZh9npZXBIAdq1cCvycPaM29OT+LoBj5jdeydA81DKYSg==", "dev": true, - "license": "MIT", "dependencies": { + "@mdit/helper": "0.14.0", "@types/markdown-it": "^14.1.2" }, "engines": { @@ -1171,12 +1024,12 @@ } }, "node_modules/@mdit/plugin-sup": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-sup/-/plugin-sup-0.13.1.tgz", - "integrity": "sha512-vkNif2Rbj7/gtk4/HJt5hnb+Dcbnek/V4HtLdtqUUnq9bIbzFBpYw5jZ1ZKKZeetDtRvOUPH5oy5d7iXAHorUg==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@mdit/plugin-sup/-/plugin-sup-0.14.0.tgz", + "integrity": "sha512-QUwuCXQHS2atYv4SFfslVsuQLI1epDBie4Sw+E7XDwnbl9/o/vcJGkqdO4HKq8d73efowlWp2tGcpCxH+AeTWA==", "dev": true, - "license": "MIT", "dependencies": { + "@mdit/helper": "0.14.0", "@types/markdown-it": "^14.1.2" }, "engines": { @@ -1191,30 +1044,11 @@ } } }, - "node_modules/@mdit/plugin-tab": { - "version": "0.13.2", - "resolved": "https://registry.npmjs.org/@mdit/plugin-tab/-/plugin-tab-0.13.2.tgz", - "integrity": "sha512-evpIXvo6vXRWhgNE6vu4ok1I2dVOzrBYmBUGc1gW8nT9MvkW9litu7RbJ6CafscqaiiYRIM5Oib1ahS0lwte6g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/markdown-it": "^14.1.2" - }, - "peerDependencies": { - "markdown-it": "^14.1.0" - }, - "peerDependenciesMeta": { - "markdown-it": { - "optional": true - } - } - }, "node_modules/@mdit/plugin-tasklist": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-tasklist/-/plugin-tasklist-0.13.1.tgz", - "integrity": "sha512-flEWnDJFEB7QZIHRwtkVjAEZe9ONiRQLRg7oazRDBM/3Z0rf28blxOx7qj2QZ/FVzQnRRZTgjFQkpiz61IckKQ==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@mdit/plugin-tasklist/-/plugin-tasklist-0.14.0.tgz", + "integrity": "sha512-qKXt3td+A4pWbAYChPgOO+Ne9dOkb3SfrbyWE15M0AsIfVDizcq4wwVp8OQ25VAU5e4VisKiZ1XOE6xRoZHCbg==", "dev": true, - "license": "MIT", "dependencies": { "@types/markdown-it": "^14.1.2" }, @@ -1231,11 +1065,10 @@ } }, "node_modules/@mdit/plugin-tex": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-tex/-/plugin-tex-0.13.1.tgz", - "integrity": "sha512-lkRf6XrfVfS11FzT3hiooWdOUPJfAd/cnAv4NN/4WU7qOEz0e0HBVQO8PQb5CPwrE94Ld4+E6rQwJfVH1grkwQ==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@mdit/plugin-tex/-/plugin-tex-0.14.0.tgz", + "integrity": "sha512-fDigmoJLm3TzcS2nHrgc70EC680QTD9v+PlUDJX8gslE489+o0jRKB6/l6YuzBdpXNRcbrDNeo8q+oODlo/Y2w==", "dev": true, - "license": "MIT", "dependencies": { "@types/markdown-it": "^14.1.2" }, @@ -1252,12 +1085,12 @@ } }, "node_modules/@mdit/plugin-uml": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-uml/-/plugin-uml-0.13.1.tgz", - "integrity": "sha512-JdCOg25OyG+QJFAba6AWwdpkaOjuht5VmOqYt4/h/AzLsIHh/2j+TnCZBn0XQm3D8yJ9Y4w4oouS4wpPduRW0A==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@mdit/plugin-uml/-/plugin-uml-0.14.0.tgz", + "integrity": "sha512-eIR4CiJfATlVAGuJh5Nd9L23zaN/ZDXc13SI/CaEPD+JG9/0h9XtyuceD5ncZDuEhmLnlxJua50Qek8NaObWDQ==", "dev": true, - "license": "MIT", "dependencies": { + "@mdit/helper": "0.14.0", "@types/markdown-it": "^14.1.2" }, "engines": { @@ -1620,9 +1453,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz", - "integrity": "sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.28.1.tgz", + "integrity": "sha512-2aZp8AES04KI2dy3Ss6/MDjXbwBzj+i0GqKtWXgw2/Ma6E4jJvujryO6gJAghIRVz7Vwr9Gtl/8na3nDUKpraQ==", "cpu": [ "arm" ], @@ -1633,9 +1466,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.0.tgz", - "integrity": "sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.28.1.tgz", + "integrity": "sha512-EbkK285O+1YMrg57xVA+Dp0tDBRB93/BZKph9XhMjezf6F4TpYjaUSuPt5J0fZXlSag0LmZAsTmdGGqPp4pQFA==", "cpu": [ "arm64" ], @@ -1646,9 +1479,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.0.tgz", - "integrity": "sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.28.1.tgz", + "integrity": "sha512-prduvrMKU6NzMq6nxzQw445zXgaDBbMQvmKSJaxpaZ5R1QDM8w+eGxo6Y/jhT/cLoCvnZI42oEqf9KQNYz1fqQ==", "cpu": [ "arm64" ], @@ -1659,9 +1492,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.0.tgz", - "integrity": "sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.28.1.tgz", + "integrity": "sha512-WsvbOunsUk0wccO/TV4o7IKgloJ942hVFK1CLatwv6TJspcCZb9umQkPdvB7FihmdxgaKR5JyxDjWpCOp4uZlQ==", "cpu": [ "x64" ], @@ -1671,10 +1504,36 @@ "darwin" ] }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.28.1.tgz", + "integrity": "sha512-HTDPdY1caUcU4qK23FeeGxCdJF64cKkqajU0iBnTVxS8F7H/7BewvYoG+va1KPSL63kQ1PGNyiwKOfReavzvNA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.28.1.tgz", + "integrity": "sha512-m/uYasxkUevcFTeRSM9TeLyPe2QDuqtjkeoTpP9SW0XxUWfcYrGDMkO/m2tTw+4NMAF9P2fU3Mw4ahNvo7QmsQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.0.tgz", - "integrity": "sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.28.1.tgz", + "integrity": "sha512-QAg11ZIt6mcmzpNE6JZBpKfJaKkqTm1A9+y9O+frdZJEuhQxiugM05gnCWiANHj4RmbgeVJpTdmKRmH/a+0QbA==", "cpu": [ "arm" ], @@ -1685,9 +1544,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.0.tgz", - "integrity": "sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.28.1.tgz", + "integrity": "sha512-dRP9PEBfolq1dmMcFqbEPSd9VlRuVWEGSmbxVEfiq2cs2jlZAl0YNxFzAQS2OrQmsLBLAATDMb3Z6MFv5vOcXg==", "cpu": [ "arm" ], @@ -1698,9 +1557,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.0.tgz", - "integrity": "sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.28.1.tgz", + "integrity": "sha512-uGr8khxO+CKT4XU8ZUH1TTEUtlktK6Kgtv0+6bIFSeiSlnGJHG1tSFSjm41uQ9sAO/5ULx9mWOz70jYLyv1QkA==", "cpu": [ "arm64" ], @@ -1711,9 +1570,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.0.tgz", - "integrity": "sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.28.1.tgz", + "integrity": "sha512-QF54q8MYGAqMLrX2t7tNpi01nvq5RI59UBNx+3+37zoKX5KViPo/gk2QLhsuqok05sSCRluj0D00LzCwBikb0A==", "cpu": [ "arm64" ], @@ -1723,10 +1582,23 @@ "linux" ] }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.28.1.tgz", + "integrity": "sha512-vPul4uodvWvLhRco2w0GcyZcdyBfpfDRgNKU+p35AWEbJ/HPs1tOUrkSueVbBS0RQHAf/A+nNtDpvw95PeVKOA==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.0.tgz", - "integrity": "sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.28.1.tgz", + "integrity": "sha512-pTnTdBuC2+pt1Rmm2SV7JWRqzhYpEILML4PKODqLz+C7Ou2apEV52h19CR7es+u04KlqplggmN9sqZlekg3R1A==", "cpu": [ "ppc64" ], @@ -1737,9 +1609,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.0.tgz", - "integrity": "sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.28.1.tgz", + "integrity": "sha512-vWXy1Nfg7TPBSuAncfInmAI/WZDd5vOklyLJDdIRKABcZWojNDY0NJwruY2AcnCLnRJKSaBgf/GiJfauu8cQZA==", "cpu": [ "riscv64" ], @@ -1750,9 +1622,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.0.tgz", - "integrity": "sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.28.1.tgz", + "integrity": "sha512-/yqC2Y53oZjb0yz8PVuGOQQNOTwxcizudunl/tFs1aLvObTclTwZ0JhXF2XcPT/zuaymemCDSuuUPXJJyqeDOg==", "cpu": [ "s390x" ], @@ -1763,9 +1635,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.0.tgz", - "integrity": "sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.28.1.tgz", + "integrity": "sha512-fzgeABz7rrAlKYB0y2kSEiURrI0691CSL0+KXwKwhxvj92VULEDQLpBYLHpF49MSiPG4sq5CK3qHMnb9tlCjBw==", "cpu": [ "x64" ], @@ -1776,9 +1648,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.0.tgz", - "integrity": "sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.28.1.tgz", + "integrity": "sha512-xQTDVzSGiMlSshpJCtudbWyRfLaNiVPXt1WgdWTwWz9n0U12cI2ZVtWe/Jgwyv/6wjL7b66uu61Vg0POWVfz4g==", "cpu": [ "x64" ], @@ -1789,9 +1661,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.0.tgz", - "integrity": "sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.28.1.tgz", + "integrity": "sha512-wSXmDRVupJstFP7elGMgv+2HqXelQhuNf+IS4V+nUpNVi/GUiBgDmfwD0UGN3pcAnWsgKG3I52wMOBnk1VHr/A==", "cpu": [ "arm64" ], @@ -1802,9 +1674,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.0.tgz", - "integrity": "sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.28.1.tgz", + "integrity": "sha512-ZkyTJ/9vkgrE/Rk9vhMXhf8l9D+eAhbAVbsGsXKy2ohmJaWg0LPQLnIxRdRp/bKyr8tXuPlXhIoGlEB5XpJnGA==", "cpu": [ "ia32" ], @@ -1815,9 +1687,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.0.tgz", - "integrity": "sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.28.1.tgz", + "integrity": "sha512-ZvK2jBafvttJjoIdKm/Q/Bh7IJ1Ose9IBOwpOXcOvW3ikGTQGmKDgxTC6oCAzW6PynbkKP8+um1du81XJHZ0JA==", "cpu": [ "x64" ], @@ -1831,74 +1703,67 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/@shikijs/core": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.22.0.tgz", - "integrity": "sha512-S8sMe4q71TJAW+qG93s5VaiihujRK6rqDFqBnxqvga/3LvqHEnxqBIOPkt//IdXVtHkQWKu4nOQNk0uBGicU7Q==", + "version": "1.24.2", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.24.2.tgz", + "integrity": "sha512-BpbNUSKIwbKrRRA+BQj0BEWSw+8kOPKDJevWeSE/xIqGX7K0xrCZQ9kK0nnEQyrzsUoka1l81ZtJ2mGaCA32HQ==", "dev": true, - "license": "MIT", "dependencies": { - "@shikijs/engine-javascript": "1.22.0", - "@shikijs/engine-oniguruma": "1.22.0", - "@shikijs/types": "1.22.0", + "@shikijs/engine-javascript": "1.24.2", + "@shikijs/engine-oniguruma": "1.24.2", + "@shikijs/types": "1.24.2", "@shikijs/vscode-textmate": "^9.3.0", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.3" } }, "node_modules/@shikijs/engine-javascript": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-1.22.0.tgz", - "integrity": "sha512-AeEtF4Gcck2dwBqCFUKYfsCq0s+eEbCEbkUuFou53NZ0sTGnJnJ/05KHQFZxpii5HMXbocV9URYVowOP2wH5kw==", + "version": "1.24.2", + "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-1.24.2.tgz", + "integrity": "sha512-EqsmYBJdLEwEiO4H+oExz34a5GhhnVp+jH9Q/XjPjmBPc6TE/x4/gD0X3i0EbkKKNqXYHHJTJUpOLRQNkEzS9Q==", "dev": true, - "license": "MIT", "dependencies": { - "@shikijs/types": "1.22.0", + "@shikijs/types": "1.24.2", "@shikijs/vscode-textmate": "^9.3.0", - "oniguruma-to-js": "0.4.3" + "oniguruma-to-es": "0.7.0" } }, "node_modules/@shikijs/engine-oniguruma": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-1.22.0.tgz", - "integrity": "sha512-5iBVjhu/DYs1HB0BKsRRFipRrD7rqjxlWTj4F2Pf+nQSPqc3kcyqFFeZXnBMzDf0HdqaFVvhDRAGiYNvyLP+Mw==", + "version": "1.24.2", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-1.24.2.tgz", + "integrity": "sha512-ZN6k//aDNWRJs1uKB12pturKHh7GejKugowOFGAuG7TxDRLod1Bd5JhpOikOiFqPmKjKEPtEA6mRCf7q3ulDyQ==", "dev": true, - "license": "MIT", "dependencies": { - "@shikijs/types": "1.22.0", + "@shikijs/types": "1.24.2", "@shikijs/vscode-textmate": "^9.3.0" } }, "node_modules/@shikijs/transformers": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/@shikijs/transformers/-/transformers-1.22.0.tgz", - "integrity": "sha512-k7iMOYuGQA62KwAuJOQBgH2IQb5vP8uiB3lMvAMGUgAMMurePOx3Z7oNqJdcpxqZP6I9cc7nc4DNqSKduCxmdg==", + "version": "1.24.2", + "resolved": "https://registry.npmjs.org/@shikijs/transformers/-/transformers-1.24.2.tgz", + "integrity": "sha512-cIwn8YSwO3bsWKJ+pezcXY1Vq0BVwvuLes1TZSC5+Awi6Tsfqhf3vBahOIqZK1rraMKOti2VEAEF/95oXMig1w==", "dev": true, - "license": "MIT", "dependencies": { - "shiki": "1.22.0" + "shiki": "1.24.2" } }, "node_modules/@shikijs/types": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-1.22.0.tgz", - "integrity": "sha512-Fw/Nr7FGFhlQqHfxzZY8Cwtwk5E9nKDUgeLjZgt3UuhcM3yJR9xj3ZGNravZZok8XmEZMiYkSMTPlPkULB8nww==", + "version": "1.24.2", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-1.24.2.tgz", + "integrity": "sha512-bdeWZiDtajGLG9BudI0AHet0b6e7FbR0EsE4jpGaI0YwHm/XJunI9+3uZnzFtX65gsyJ6ngCIWUfA4NWRPnBkQ==", "dev": true, - "license": "MIT", "dependencies": { "@shikijs/vscode-textmate": "^9.3.0", "@types/hast": "^3.0.4" } }, "node_modules/@shikijs/vscode-textmate": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-9.3.0.tgz", - "integrity": "sha512-jn7/7ky30idSkd/O5yDBfAnVt+JJpepofP/POZ1iMOxK59cOfqIgg/Dj0eFsjOTMw+4ycJN0uhZH/Eb0bs/EUA==", - "dev": true, - "license": "MIT" + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-9.3.1.tgz", + "integrity": "sha512-79QfK1393x9Ho60QFyLti+QfdJzRQCVLFb97kOIV7Eo9vQU/roINgk7m24uv0a7AUvN//RDH36FLjjK48v0s9g==", + "dev": true }, "node_modules/@sideway/address": { "version": "4.1.5", @@ -1938,8 +1803,7 @@ "version": "1.11.0", "resolved": "https://registry.npmjs.org/@stackblitz/sdk/-/sdk-1.11.0.tgz", "integrity": "sha512-DFQGANNkEZRzFk1/rDP6TcFdM82ycHE+zfl9C/M/jXlH68jiqHWHFMQURLELoD8koxvu/eW5uhg94NSAZlYrUQ==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/@types/d3": { "version": "7.4.3", @@ -2239,7 +2103,6 @@ "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", "dev": true, - "license": "MIT", "dependencies": { "@types/unist": "*" } @@ -2258,8 +2121,7 @@ "version": "0.16.7", "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.7.tgz", "integrity": "sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/@types/linkify-it": { "version": "5.0.0", @@ -2282,7 +2144,6 @@ "resolved": "https://registry.npmjs.org/@types/markdown-it-emoji/-/markdown-it-emoji-3.0.1.tgz", "integrity": "sha512-cz1j8R35XivBqq9mwnsrP2fsz2yicLhB8+PDtuVkKOExwEdsVBNI+ROL3sbhtR5occRZ66vT0QnwFZCqdjf3pA==", "dev": true, - "license": "MIT", "dependencies": { "@types/markdown-it": "^14" } @@ -2292,7 +2153,6 @@ "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", "dev": true, - "license": "MIT", "dependencies": { "@types/unist": "*" } @@ -2330,7 +2190,6 @@ "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz", "integrity": "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==", "dev": true, - "license": "MIT", "dependencies": { "@types/node": "*" } @@ -2358,8 +2217,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/@types/web-bluetooth": { "version": "0.0.20", @@ -2378,22 +2236,21 @@ } }, "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true, - "license": "ISC" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.1.tgz", + "integrity": "sha512-fEzPV3hSkSMltkw152tJKNARhOupqbH96MZWyRjNaYZOMIzbrTeQDG+MTc6Mr2pgzFQzFxAfmhGDNP5QK++2ZA==", + "dev": true }, "node_modules/@vitejs/plugin-vue": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.1.4.tgz", - "integrity": "sha512-N2XSI2n3sQqp5w7Y/AN/L2XDjBIRGqXko+eDp42sydYSBeJuSm5a1sLf8zakmo8u7tA8NmBgoDLA1HeOESjp9A==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.2.1.tgz", + "integrity": "sha512-cxh314tzaWwOLqVes2gnnCtvBDcM1UMdn+iFR+UjAn411dPT3tOmqrJjbMd7koZpMAmBM/GqeV4n9ge7JSiJJQ==", "dev": true, "engines": { "node": "^18.0.0 || >=20.0.0" }, "peerDependencies": { - "vite": "^5.0.0", + "vite": "^5.0.0 || ^6.0.0", "vue": "^3.2.25" } }, @@ -2454,13 +2311,12 @@ "dev": true }, "node_modules/@vue/devtools-kit": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.5.2.tgz", - "integrity": "sha512-0leUOE2HBfl8sHf9ePKzxqnCFskkU22tWWqd9OfeSlslAKE30/TViYvWcF4vgQmPlJnAAdHU0WfW5dYlCeOiuw==", + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.6.8.tgz", + "integrity": "sha512-JhJ8M3sPU+v0P2iZBF2DkdmR9L0dnT5RXJabJqX6o8KtFs3tebdvfoXV2Dm3BFuqeECuMJIfF1aCzSt+WQ4wrw==", "dev": true, - "license": "MIT", "dependencies": { - "@vue/devtools-shared": "^7.5.2", + "@vue/devtools-shared": "^7.6.8", "birpc": "^0.2.19", "hookable": "^5.5.3", "mitt": "^3.0.1", @@ -2470,11 +2326,10 @@ } }, "node_modules/@vue/devtools-shared": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.5.2.tgz", - "integrity": "sha512-+zmcixnD6TAo+zwm30YuwZckhL9iIi4u+gFwbq9C8zpm3SMndTlEYZtNhAHUhOXB+bCkzyunxw80KQ/T0trF4w==", + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.6.8.tgz", + "integrity": "sha512-9MBPO5Z3X1nYGFqTJyohl6Gmf/J7UNN1oicHdyzBVZP4jnhZ4c20MgtaHDIzWmHDHCMYVS5bwKxT3jxh7gOOKA==", "dev": true, - "license": "MIT", "dependencies": { "rfdc": "^1.4.1" } @@ -2530,53 +2385,50 @@ "dev": true }, "node_modules/@vuepress/bundler-vite": { - "version": "2.0.0-rc.18", - "resolved": "https://registry.npmjs.org/@vuepress/bundler-vite/-/bundler-vite-2.0.0-rc.18.tgz", - "integrity": "sha512-Q+OUul4OLIS4OLuKqIlmJKHhW5Edt5i6fVY6infgGhb4tUQt3z37DjCUtvbMikb05Va9YqtTAGt2eCWOk7eGPw==", + "version": "2.0.0-rc.19", + "resolved": "https://registry.npmjs.org/@vuepress/bundler-vite/-/bundler-vite-2.0.0-rc.19.tgz", + "integrity": "sha512-Vn0wEVRcdAld+8NJeELSwrj5JEPObRn0xpRWtAau/UwVWHmMLo16RRkTvXdjSiwpDWeP/9ztC5buyTXVoeb7Dw==", "dev": true, - "license": "MIT", "dependencies": { - "@vitejs/plugin-vue": "^5.1.4", - "@vuepress/bundlerutils": "2.0.0-rc.18", - "@vuepress/client": "2.0.0-rc.18", - "@vuepress/core": "2.0.0-rc.18", - "@vuepress/shared": "2.0.0-rc.18", - "@vuepress/utils": "2.0.0-rc.18", + "@vitejs/plugin-vue": "^5.2.1", + "@vuepress/bundlerutils": "2.0.0-rc.19", + "@vuepress/client": "2.0.0-rc.19", + "@vuepress/core": "2.0.0-rc.19", + "@vuepress/shared": "2.0.0-rc.19", + "@vuepress/utils": "2.0.0-rc.19", "autoprefixer": "^10.4.20", "connect-history-api-fallback": "^2.0.0", - "postcss": "^8.4.47", + "postcss": "^8.4.49", "postcss-load-config": "^6.0.1", - "rollup": "^4.24.0", - "vite": "~5.4.8", - "vue": "^3.5.11", - "vue-router": "^4.4.5" + "rollup": "^4.28.1", + "vite": "~6.0.3", + "vue": "^3.5.13", + "vue-router": "^4.5.0" } }, "node_modules/@vuepress/bundlerutils": { - "version": "2.0.0-rc.18", - "resolved": "https://registry.npmjs.org/@vuepress/bundlerutils/-/bundlerutils-2.0.0-rc.18.tgz", - "integrity": "sha512-GTcdc78cfcKqn/D3xPrxGFeR+WPV2zJE82jpKAnIa4I30aScq/95pYF1FofP0Gdc+0/XQCxFQ8xiT8iYcoQPSw==", + "version": "2.0.0-rc.19", + "resolved": "https://registry.npmjs.org/@vuepress/bundlerutils/-/bundlerutils-2.0.0-rc.19.tgz", + "integrity": "sha512-ln5htptK14OMJV3yeGRxAwYhSkVxrTwEHEaifeWrFvjuNxj2kLmkCl7MDdzr232jSOWwkCcmbOyafbxMsaRDkQ==", "dev": true, - "license": "MIT", "dependencies": { - "@vuepress/client": "2.0.0-rc.18", - "@vuepress/core": "2.0.0-rc.18", - "@vuepress/shared": "2.0.0-rc.18", - "@vuepress/utils": "2.0.0-rc.18", - "vue": "^3.5.11", - "vue-router": "^4.4.5" + "@vuepress/client": "2.0.0-rc.19", + "@vuepress/core": "2.0.0-rc.19", + "@vuepress/shared": "2.0.0-rc.19", + "@vuepress/utils": "2.0.0-rc.19", + "vue": "^3.5.13", + "vue-router": "^4.5.0" } }, "node_modules/@vuepress/cli": { - "version": "2.0.0-rc.18", - "resolved": "https://registry.npmjs.org/@vuepress/cli/-/cli-2.0.0-rc.18.tgz", - "integrity": "sha512-9Oxyb22klpBNzia+2D4NRGv+Jk0+TwHX8Pn25cy9TlyxMeh9+jFioXT0Jc3c9/vOesBaCI6JxSxwPqtgRFr1rQ==", + "version": "2.0.0-rc.19", + "resolved": "https://registry.npmjs.org/@vuepress/cli/-/cli-2.0.0-rc.19.tgz", + "integrity": "sha512-QFicPNIj3RZAJbHoLbeYlPJsPchnQLGuw0n8xv0eeUi9ejEXO1huWA8sLoPbTGdiDW+PHr1MHnaVMkyUfwaKcQ==", "dev": true, - "license": "MIT", "dependencies": { - "@vuepress/core": "2.0.0-rc.18", - "@vuepress/shared": "2.0.0-rc.18", - "@vuepress/utils": "2.0.0-rc.18", + "@vuepress/core": "2.0.0-rc.19", + "@vuepress/shared": "2.0.0-rc.19", + "@vuepress/utils": "2.0.0-rc.19", "cac": "^6.7.14", "chokidar": "^3.6.0", "envinfo": "^7.14.0", @@ -2587,69 +2439,64 @@ } }, "node_modules/@vuepress/client": { - "version": "2.0.0-rc.18", - "resolved": "https://registry.npmjs.org/@vuepress/client/-/client-2.0.0-rc.18.tgz", - "integrity": "sha512-ImeF10uwZvQt3KyYN+fdyPRCZmzEJ2r4sTxC/39ieVA4BzPpTzrJwBNT3KONYkckaoXnBXIoI8d+DWFfq9B9NQ==", + "version": "2.0.0-rc.19", + "resolved": "https://registry.npmjs.org/@vuepress/client/-/client-2.0.0-rc.19.tgz", + "integrity": "sha512-vUAU6n4qmtXqthxkb4LHq0D+VWSDenwBDf0jUs7RaBLuOVrbPtmH/hs4k1vLIlGdwC3Zs/G6tlB4UmuZiiwR8Q==", "dev": true, - "license": "MIT", "dependencies": { - "@vue/devtools-api": "^7.4.6", - "@vuepress/shared": "2.0.0-rc.18", - "vue": "^3.5.11", - "vue-router": "^4.4.5" + "@vue/devtools-api": "^7.6.7", + "@vuepress/shared": "2.0.0-rc.19", + "vue": "^3.5.13", + "vue-router": "^4.5.0" } }, "node_modules/@vuepress/client/node_modules/@vue/devtools-api": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.5.2.tgz", - "integrity": "sha512-VxPbAQxJrYSIkoGVvQ2oOoKW8u4CMpvRLySTxhoJA38z8bQEGy9GO33eoRY/DulJbSFRfjZFNvH+dh8B4qpesQ==", + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.6.8.tgz", + "integrity": "sha512-ma6dY/sZR36zALVsV1W7eC57c6IJPXsy8SNgZn1PLVWU4z4dPn5TIBmnF4stmdJ4sQcixqKaQ8pwjbMPzEZwiA==", "dev": true, - "license": "MIT", "dependencies": { - "@vue/devtools-kit": "^7.5.2" + "@vue/devtools-kit": "^7.6.8" } }, "node_modules/@vuepress/core": { - "version": "2.0.0-rc.18", - "resolved": "https://registry.npmjs.org/@vuepress/core/-/core-2.0.0-rc.18.tgz", - "integrity": "sha512-ikQ5EyA1jZynk1amsihG0cX6kWTgCIsbGCBgPWDVfkSPCrYCxxaIfzvKgyGBiNBFZ7kqoxuMnEn8EaY/fhSL0A==", + "version": "2.0.0-rc.19", + "resolved": "https://registry.npmjs.org/@vuepress/core/-/core-2.0.0-rc.19.tgz", + "integrity": "sha512-rvmBPMIWS2dey/2QjxZoO0OcrUU46NE3mSLk3oU7JOP0cG7xvRxf6U1OXiwYLC3fPO4g6XbHiKe6gihkmL6VDA==", "dev": true, - "license": "MIT", "dependencies": { - "@vuepress/client": "2.0.0-rc.18", - "@vuepress/markdown": "2.0.0-rc.18", - "@vuepress/shared": "2.0.0-rc.18", - "@vuepress/utils": "2.0.0-rc.18", - "vue": "^3.5.11" + "@vuepress/client": "2.0.0-rc.19", + "@vuepress/markdown": "2.0.0-rc.19", + "@vuepress/shared": "2.0.0-rc.19", + "@vuepress/utils": "2.0.0-rc.19", + "vue": "^3.5.13" } }, "node_modules/@vuepress/helper": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/helper/-/helper-2.0.0-rc.56.tgz", - "integrity": "sha512-O4iGck8PnloYypgRx6w+Vc/yG7wi7pyli0FZo82LNx/6OmZAdilFUIacLO3Cr0HLmpX9sK6NzQJeJ4HAgsiIUw==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/helper/-/helper-2.0.0-rc.66.tgz", + "integrity": "sha512-T/1hzQwT1ShJDOgTvxUXt9Uydmik8cMnOAT6Bpv3OrmhyprSxJ4Riu1gYdn6W5VLf+MD9sUjTvwPAyixvwsI6w==", "dev": true, - "license": "MIT", "dependencies": { - "@vue/shared": "^3.5.12", - "@vueuse/core": "^11.1.0", + "@vue/shared": "^3.5.13", + "@vueuse/core": "^12.0.0", "cheerio": "1.0.0", "fflate": "^0.8.2", "gray-matter": "^4.0.3", - "vue": "^3.5.12" + "vue": "^3.5.13" }, "peerDependencies": { - "vuepress": "2.0.0-rc.18" + "vuepress": "2.0.0-rc.19" } }, "node_modules/@vuepress/highlighter-helper": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/highlighter-helper/-/highlighter-helper-2.0.0-rc.56.tgz", - "integrity": "sha512-ol7bOQdg5/CxGYMCDV6ucQKT2AeJTLKc6I4OwzzMjkiBEH/u3PNyq5rDXFr6pgSmlboZ5Clx9H7aajXfYilY+w==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/highlighter-helper/-/highlighter-helper-2.0.0-rc.66.tgz", + "integrity": "sha512-RxhUIR+GFXXjCy5aFHHLvIKPcyyDhyzmka7shV+xr/vaU+EDbnQFrF67qo9pLDfzJc0KKTL9cKo4CcjkAoZ/tQ==", "dev": true, - "license": "MIT", "peerDependencies": { - "@vueuse/core": "^11.1.0", - "vuepress": "2.0.0-rc.18" + "@vueuse/core": "^12.0.0", + "vuepress": "2.0.0-rc.19" }, "peerDependenciesMeta": { "@vueuse/core": { @@ -2658,11 +2505,10 @@ } }, "node_modules/@vuepress/markdown": { - "version": "2.0.0-rc.18", - "resolved": "https://registry.npmjs.org/@vuepress/markdown/-/markdown-2.0.0-rc.18.tgz", - "integrity": "sha512-RUX7rgjONBwOepWXqB4SzI2Tbm6zEYK2YTHwjexzAIBr+nxgB+B8nizdr+VvuVk7Ehn/CtcyXhBdf1NZh9UgUQ==", + "version": "2.0.0-rc.19", + "resolved": "https://registry.npmjs.org/@vuepress/markdown/-/markdown-2.0.0-rc.19.tgz", + "integrity": "sha512-6jgUXhpEK55PEEGtPhz7Hq/JqTbLU8n9w2D7emXiK2FYcbeKpjoRIbVRzmzB/dXeK3NzHChANu2IIqpOT6Ba1w==", "dev": true, - "license": "MIT", "dependencies": { "@mdit-vue/plugin-component": "^2.1.3", "@mdit-vue/plugin-frontmatter": "^2.1.3", @@ -2674,8 +2520,8 @@ "@mdit-vue/types": "^2.1.0", "@types/markdown-it": "^14.1.2", "@types/markdown-it-emoji": "^3.0.1", - "@vuepress/shared": "2.0.0-rc.18", - "@vuepress/utils": "2.0.0-rc.18", + "@vuepress/shared": "2.0.0-rc.19", + "@vuepress/utils": "2.0.0-rc.19", "markdown-it": "^14.1.0", "markdown-it-anchor": "^9.2.0", "markdown-it-emoji": "^3.0.0", @@ -2683,79 +2529,74 @@ } }, "node_modules/@vuepress/plugin-active-header-links": { - "version": "2.0.0-rc.55", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-active-header-links/-/plugin-active-header-links-2.0.0-rc.55.tgz", - "integrity": "sha512-HwcvQpFhoyxURxalOO72L6cUM5yMcqKS/QFpaZvaob8pQBgZfJTH+77dfKEmz4rbf+WBMHrUEMfTICeJvu0Frw==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-active-header-links/-/plugin-active-header-links-2.0.0-rc.66.tgz", + "integrity": "sha512-3Rk5G8yheN14PQrFushePD+xLDnfmHCgxmPEtnF+9Sw1yfBSkYubpWy6NJLGW0zyPUaabTcoUXwNlzsf0swCKw==", "dev": true, - "license": "MIT", "dependencies": { - "@vueuse/core": "^11.1.0", - "vue": "^3.5.12" + "@vueuse/core": "^12.0.0", + "vue": "^3.5.13" }, "peerDependencies": { - "vuepress": "2.0.0-rc.18" + "vuepress": "2.0.0-rc.19" } }, "node_modules/@vuepress/plugin-back-to-top": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-back-to-top/-/plugin-back-to-top-2.0.0-rc.56.tgz", - "integrity": "sha512-qlX/VHX3RRQnZIGrIqVNb+zwwPjV/9FMt8e/aITxp0gpaGaddOS8FFwVK8tOuKAJQVnq+QHJZtO+RdguS5216g==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-back-to-top/-/plugin-back-to-top-2.0.0-rc.66.tgz", + "integrity": "sha512-UeYLwjMV7zWbIR8iURDtzSfWQWKefSrYT/v6uo8XXhuC1U5IZD/MYlp+/H8EMQMYzmm4tqkbbsSSmlIdQBTpfw==", "dev": true, - "license": "MIT", "dependencies": { - "@vuepress/helper": "2.0.0-rc.56", - "@vueuse/core": "^11.1.0", - "vue": "^3.5.12" + "@vuepress/helper": "2.0.0-rc.66", + "@vueuse/core": "^12.0.0", + "vue": "^3.5.13" }, "peerDependencies": { - "vuepress": "2.0.0-rc.18" + "vuepress": "2.0.0-rc.19" } }, "node_modules/@vuepress/plugin-blog": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-blog/-/plugin-blog-2.0.0-rc.56.tgz", - "integrity": "sha512-zV4zZ8tGvOaVNJGLswoDzCkzAx6lTjuGf51EM2qHGvRuGuc0vjuOb8vtDD4s7Idtjmiu4x/s+waPPy2r8Aalbw==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-blog/-/plugin-blog-2.0.0-rc.66.tgz", + "integrity": "sha512-Bbq8diNv/4TTftj8Ncc4Uc9PbL4t0pypP5j/uGL5eJZgqDVwKxGKTZ4dkM07U7j/dzIpPeKYnfxc0DIY9KYq/w==", "dev": true, - "license": "MIT", "dependencies": { - "@vuepress/helper": "2.0.0-rc.56", + "@vuepress/helper": "2.0.0-rc.66", "chokidar": "^3.6.0", - "vue": "^3.5.12" + "vue": "^3.5.13" }, "peerDependencies": { - "vuepress": "2.0.0-rc.18" + "vuepress": "2.0.0-rc.19" } }, "node_modules/@vuepress/plugin-catalog": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-catalog/-/plugin-catalog-2.0.0-rc.56.tgz", - "integrity": "sha512-OsxujnVqQKyax+dC2QHTKdeO6aL62ZP1A7cgzBZDNIRGLYZjeTIypt2XT13OxisNm0pXzWBrqcv5zYQo+VvOrg==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-catalog/-/plugin-catalog-2.0.0-rc.66.tgz", + "integrity": "sha512-vIpfKnUJ2wtVk4JjLa7h91tN7LUi9rWTwrtiRCtUeRkkX9HX/VlxcnVFVIzClNwo0vTRuIVnMsIfKbta5QKZIw==", "dev": true, - "license": "MIT", "dependencies": { - "@vuepress/helper": "2.0.0-rc.56", - "vue": "^3.5.12" + "@vuepress/helper": "2.0.0-rc.66", + "vue": "^3.5.13" }, "peerDependencies": { - "vuepress": "2.0.0-rc.18" + "vuepress": "2.0.0-rc.19" } }, "node_modules/@vuepress/plugin-comment": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-comment/-/plugin-comment-2.0.0-rc.56.tgz", - "integrity": "sha512-R26A434260YbYd6X5qdRo4CvW9/694+5us5NKFoiTo7HByx+4cblmddy5K6q40cfTcvbbnATVAUxVTDIPO7SFw==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-comment/-/plugin-comment-2.0.0-rc.66.tgz", + "integrity": "sha512-Rvr7EH7BTv1xSuUWoVWHj4iErSelDYgtKwkDQ2uJYVFwvV1y2ue5eInWSsCQdESZG52AbFO/UobQNbpCXp+v+A==", "dev": true, - "license": "MIT", "dependencies": { - "@vuepress/helper": "2.0.0-rc.56", + "@vuepress/helper": "2.0.0-rc.66", "giscus": "^1.5.0", - "vue": "^3.5.12" + "vue": "^3.5.13" }, "peerDependencies": { - "@waline/client": "^3.3.1", + "@waline/client": "^3.4.1", "artalk": "^2.9.0", "twikoo": "^1.6.39", - "vuepress": "2.0.0-rc.18" + "vuepress": "2.0.0-rc.19" }, "peerDependenciesMeta": { "@waline/client": { @@ -2770,46 +2611,43 @@ } }, "node_modules/@vuepress/plugin-copy-code": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-copy-code/-/plugin-copy-code-2.0.0-rc.56.tgz", - "integrity": "sha512-f8lr7R66oOeH5WWuASwI683SPKmsH+6tCSrDc0fpRTprPIdKWMc7tbjMNLpzCDseqZUbvGGuBO7bl3LeIMSO4A==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-copy-code/-/plugin-copy-code-2.0.0-rc.66.tgz", + "integrity": "sha512-9z7R3d0qlQY5NnfsviqHRTVbjvq0n5ngdSpZc/yekl4/NmfgKqVuTqbFwirlj/vTcGqZwn2YfEu0v/nM3TLalA==", "dev": true, - "license": "MIT", "dependencies": { - "@vuepress/helper": "2.0.0-rc.56", - "@vueuse/core": "^11.1.0", - "vue": "^3.5.12" + "@vuepress/helper": "2.0.0-rc.66", + "@vueuse/core": "^12.0.0", + "vue": "^3.5.13" }, "peerDependencies": { - "vuepress": "2.0.0-rc.18" + "vuepress": "2.0.0-rc.19" } }, "node_modules/@vuepress/plugin-copyright": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-copyright/-/plugin-copyright-2.0.0-rc.56.tgz", - "integrity": "sha512-4eLwtD4xOMLLxjkNBhJ9tLHEmCE4YKDRnRcdwc4OUzuCy8d/r+5Djwnv+sDDxqgNIZQISCd8UG0hFjwsOBx6Tg==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-copyright/-/plugin-copyright-2.0.0-rc.66.tgz", + "integrity": "sha512-B15VxyeUWMeUMRRnRWjaY1f81mPoJZvSW2otBy0zcFxfQ2IHvbRoy5nQL/s46bUhzdeVfCRNKKMYbqMofZa89A==", "dev": true, - "license": "MIT", "dependencies": { - "@vuepress/helper": "2.0.0-rc.56", - "@vueuse/core": "^11.1.0", - "vue": "^3.5.12" + "@vuepress/helper": "2.0.0-rc.66", + "@vueuse/core": "^12.0.0", + "vue": "^3.5.13" }, "peerDependencies": { - "vuepress": "2.0.0-rc.18" + "vuepress": "2.0.0-rc.19" } }, "node_modules/@vuepress/plugin-git": { - "version": "2.0.0-rc.54", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-git/-/plugin-git-2.0.0-rc.54.tgz", - "integrity": "sha512-Yy0elQlKt+2GbeUI+mZMGdbkvCsPXep+lBLaXYQqiIcHC4tXAwj+1FwB18LTICiv3oQDHUtx7ZZwTnYejXJ7sg==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-git/-/plugin-git-2.0.0-rc.66.tgz", + "integrity": "sha512-GiAniZY/gI5u5La3/+qqKrDyYLZoEdE3N81buh4Nmf9K9RGSPw8mb/+XJ2q58zX8plPn925YXverfjkJLYxWyg==", "dev": true, - "license": "MIT", "dependencies": { - "execa": "^9.4.0" + "execa": "^9.5.2" }, "peerDependencies": { - "vuepress": "2.0.0-rc.18" + "vuepress": "2.0.0-rc.19" } }, "node_modules/@vuepress/plugin-git/node_modules/@sindresorhus/merge-streams": { @@ -2817,7 +2655,6 @@ "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=18" }, @@ -2826,11 +2663,10 @@ } }, "node_modules/@vuepress/plugin-git/node_modules/execa": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-9.4.1.tgz", - "integrity": "sha512-5eo/BRqZm3GYce+1jqX/tJ7duA2AnE39i88fuedNFUV8XxGxUpF3aWkBRfbUcjV49gCkvS/pzc0YrCPhaIewdg==", + "version": "9.5.2", + "resolved": "https://registry.npmjs.org/execa/-/execa-9.5.2.tgz", + "integrity": "sha512-EHlpxMCpHWSAh1dgS6bVeoLAXGnJNdR93aabr4QCGbzOM73o5XmRfM/e5FUqsw3aagP8S8XEWUWFAxnRBnAF0Q==", "dev": true, - "license": "MIT", "dependencies": { "@sindresorhus/merge-streams": "^4.0.0", "cross-spawn": "^7.0.3", @@ -2857,7 +2693,6 @@ "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz", "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==", "dev": true, - "license": "MIT", "dependencies": { "is-unicode-supported": "^2.0.0" }, @@ -2873,7 +2708,6 @@ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", "dev": true, - "license": "MIT", "dependencies": { "@sec-ant/readable-stream": "^0.4.1", "is-stream": "^4.0.1" @@ -2890,7 +2724,6 @@ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.0.tgz", "integrity": "sha512-/1/GPCpDUCCYwlERiYjxoczfP0zfvZMU/OWgQPMya9AbAE24vseigFdhAMObpc8Q4lc/kjutPfUddDYyAmejnA==", "dev": true, - "license": "Apache-2.0", "engines": { "node": ">=18.18.0" } @@ -2900,7 +2733,6 @@ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", "dev": true, - "license": "MIT", "engines": { "node": ">=18" }, @@ -2913,7 +2745,6 @@ "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=18" }, @@ -2926,7 +2757,6 @@ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz", "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==", "dev": true, - "license": "MIT", "dependencies": { "path-key": "^4.0.0", "unicorn-magic": "^0.3.0" @@ -2943,7 +2773,6 @@ "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=12" }, @@ -2956,7 +2785,6 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, - "license": "ISC", "engines": { "node": ">=14" }, @@ -2969,7 +2797,6 @@ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz", "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==", "dev": true, - "license": "MIT", "engines": { "node": ">=18" }, @@ -2982,7 +2809,6 @@ "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", "dev": true, - "license": "MIT", "engines": { "node": ">=18" }, @@ -2991,39 +2817,72 @@ } }, "node_modules/@vuepress/plugin-links-check": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-links-check/-/plugin-links-check-2.0.0-rc.56.tgz", - "integrity": "sha512-5eyiI4zABfEyJ79xudilPx+jG4dhZ6ZQw7ZPs3nhsmpSsOsnbfBUjzRq0vYf5BVrSSmPIu9yFX+YcVZej2uvZg==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-links-check/-/plugin-links-check-2.0.0-rc.66.tgz", + "integrity": "sha512-B3xBdEjRMvhufLTSxLbWSRTKYsqnXWGZJSGZnk6mLzVdxmMXXHPacpaepF9WON26gUAnvWct7Uyg121l54aUSQ==", + "dev": true, + "dependencies": { + "@vuepress/helper": "2.0.0-rc.66" + }, + "peerDependencies": { + "vuepress": "2.0.0-rc.19" + } + }, + "node_modules/@vuepress/plugin-markdown-ext": { + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-markdown-ext/-/plugin-markdown-ext-2.0.0-rc.66.tgz", + "integrity": "sha512-heSwOXrgh0hGDxDD6zCfi4xe1Uaz4GgguWdnWEMl1ewhssjjhC07be/FNt9wwWKjTJkkKHsdTUwyKV0R+mL3Gw==", "dev": true, - "license": "MIT", "dependencies": { - "@vuepress/helper": "2.0.0-rc.56" + "@mdit/plugin-container": "^0.14.0", + "@mdit/plugin-footnote": "^0.14.0", + "@mdit/plugin-tasklist": "^0.14.0", + "@types/markdown-it": "^14.1.2", + "@vuepress/helper": "2.0.0-rc.66", + "js-yaml": "^4.1.0" }, "peerDependencies": { - "vuepress": "2.0.0-rc.18" + "vuepress": "2.0.0-rc.19" + } + }, + "node_modules/@vuepress/plugin-markdown-ext/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/@vuepress/plugin-markdown-ext/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, "node_modules/@vuepress/plugin-markdown-hint": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-markdown-hint/-/plugin-markdown-hint-2.0.0-rc.56.tgz", - "integrity": "sha512-qVOlqBIMjySormRde0uo/rILIC8BP59GIz+lRk8XpO5G92ejmJlRck27Pjrzm5NngR+pOonWfZ7yjGtT35U6nA==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-markdown-hint/-/plugin-markdown-hint-2.0.0-rc.66.tgz", + "integrity": "sha512-VZiZw+IexDe/+lgncmvbq8w+rwJCMYnTC181ZA5kIl5wiiOHY6U5gFdZ16TnlQB6MjARO8b2F5j+WDZTkS6J2w==", "dev": true, - "license": "MIT", "dependencies": { - "@mdit/plugin-alert": "^0.13.1", - "@mdit/plugin-container": "^0.13.1", + "@mdit/plugin-alert": "^0.14.0", + "@mdit/plugin-container": "^0.14.0", "@types/markdown-it": "^14.1.2", - "@vuepress/helper": "2.0.0-rc.56", - "@vueuse/core": "^11.1.0" + "@vuepress/helper": "2.0.0-rc.66", + "@vueuse/core": "^12.0.0" }, "peerDependencies": { - "vuepress": "2.0.0-rc.18" + "vuepress": "2.0.0-rc.19" } }, "node_modules/@vuepress/plugin-markdown-image": { - "version": "2.0.0-rc.62", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-markdown-image/-/plugin-markdown-image-2.0.0-rc.62.tgz", - "integrity": "sha512-0fvGgj+iumJI0DezBfbCn0HglNhqQrObV6Gfou17U8k7FCZf8NoS4JgAd7Bj8PptGUbtaGnxiID54Hf0C9AKDw==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-markdown-image/-/plugin-markdown-image-2.0.0-rc.66.tgz", + "integrity": "sha512-+86SH1DRNB3Ek+L2deySlmW7HTBjLXFdLqxumry69NxzksHGFb03/1zKn48dfLVGceUX1339cQTf5RexSHEz0Q==", "dev": true, "dependencies": { "@mdit/plugin-figure": "^0.14.0", @@ -3031,10 +2890,10 @@ "@mdit/plugin-img-mark": "^0.14.0", "@mdit/plugin-img-size": "^0.14.0", "@types/markdown-it": "^14.1.2", - "@vuepress/helper": "2.0.0-rc.62" + "@vuepress/helper": "2.0.0-rc.66" }, "peerDependencies": { - "vuepress": "2.0.0-rc.18" + "vuepress": "2.0.0-rc.19" } }, "node_modules/@vuepress/plugin-markdown-image/node_modules/@mdit/plugin-figure": { @@ -3117,76 +2976,36 @@ } } }, - "node_modules/@vuepress/plugin-markdown-image/node_modules/@vuepress/helper": { - "version": "2.0.0-rc.62", - "resolved": "https://registry.npmjs.org/@vuepress/helper/-/helper-2.0.0-rc.62.tgz", - "integrity": "sha512-O6I9iliP1UxSI0g2PfLyx/WqvuKtGdcUl1DlxMQAw/YRfjbvcVIetV/htiUA3C8H5+RgJXvzRX/Zruik2aiuGg==", + "node_modules/@vuepress/plugin-markdown-include": { + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-markdown-include/-/plugin-markdown-include-2.0.0-rc.66.tgz", + "integrity": "sha512-B3dlrQNbU1ItOsWR7QOyZ4yfPfzzZ88ri0ORQCocq0Q6oJGSI6kUoPs9yOBrfW6chNuPc+IdJgqgHpWWu9Lp7A==", "dev": true, "dependencies": { - "@vue/shared": "^3.5.13", - "@vueuse/core": "^12.0.0", - "cheerio": "1.0.0", - "fflate": "^0.8.2", - "gray-matter": "^4.0.3", - "vue": "^3.5.13" + "@mdit/plugin-include": "^0.14.0", + "@types/markdown-it": "^14.1.2", + "@vuepress/helper": "2.0.0-rc.66" }, "peerDependencies": { - "vuepress": "2.0.0-rc.18" - } - }, - "node_modules/@vuepress/plugin-markdown-image/node_modules/@vueuse/core": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-12.0.0.tgz", - "integrity": "sha512-C12RukhXiJCbx4MGhjmd/gH52TjJsc3G0E0kQj/kb19H3Nt6n1CA4DRWuTdWWcaFRdlTe0npWDS942mvacvNBw==", - "dev": true, - "dependencies": { - "@types/web-bluetooth": "^0.0.20", - "@vueuse/metadata": "12.0.0", - "@vueuse/shared": "12.0.0", - "vue": "^3.5.13" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/@vuepress/plugin-markdown-image/node_modules/@vueuse/metadata": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-12.0.0.tgz", - "integrity": "sha512-Yzimd1D3sjxTDOlF05HekU5aSGdKjxhuhRFHA7gDWLn57PRbBIh+SF5NmjhJ0WRgF3my7T8LBucyxdFJjIfRJQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/@vuepress/plugin-markdown-image/node_modules/@vueuse/shared": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-12.0.0.tgz", - "integrity": "sha512-3i6qtcq2PIio5i/vVYidkkcgvmTjCqrf26u+Fd4LhnbBmIT6FN8y6q/GJERp8lfcB9zVEfjdV0Br0443qZuJpw==", - "dev": true, - "dependencies": { - "vue": "^3.5.13" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" + "vuepress": "2.0.0-rc.19" } }, "node_modules/@vuepress/plugin-markdown-math": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-markdown-math/-/plugin-markdown-math-2.0.0-rc.56.tgz", - "integrity": "sha512-I5+m+siib1m0+u9XCdmtGq2AyGg34l9HVAzCeJajVhA0/LUFdvqjxfVIg9ymuTqsspB8IW+x5O+acE6jznRdig==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-markdown-math/-/plugin-markdown-math-2.0.0-rc.66.tgz", + "integrity": "sha512-X9N6IlgZfivJKv43j7Kpya2BHQs3U969FMvZNhSJmIrloqhAWlBPA6O97cL+P4jnid/obfp585rz9Ecc1/Qx1w==", "dev": true, - "license": "MIT", "dependencies": { - "@mdit/plugin-katex-slim": "^0.13.1", - "@mdit/plugin-mathjax-slim": "^0.13.1", + "@mdit/plugin-katex-slim": "^0.14.0", + "@mdit/plugin-mathjax-slim": "^0.14.0", "@types/markdown-it": "^14.1.2", - "@vuepress/helper": "2.0.0-rc.56", - "vue": "^3.5.12" + "@vuepress/helper": "2.0.0-rc.66", + "vue": "^3.5.13" }, "peerDependencies": { "katex": "^0.16.10", "mathjax-full": "^3.2.2", - "vuepress": "2.0.0-rc.18" + "vuepress": "2.0.0-rc.19" }, "peerDependenciesMeta": { "katex": { @@ -3197,20 +3016,40 @@ } } }, + "node_modules/@vuepress/plugin-markdown-stylize": { + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-markdown-stylize/-/plugin-markdown-stylize-2.0.0-rc.66.tgz", + "integrity": "sha512-e8JoHkILmVcq0DMWbDVrHg7SuphHPA6kIRgk01khK2c9b2BFAEd7T4xjpcp/ISfbebc0PA7F0z3z6IVT/vfwJQ==", + "dev": true, + "dependencies": { + "@mdit/plugin-align": "^0.14.0", + "@mdit/plugin-attrs": "^0.14.0", + "@mdit/plugin-mark": "^0.14.0", + "@mdit/plugin-spoiler": "^0.14.0", + "@mdit/plugin-stylize": "^0.14.0", + "@mdit/plugin-sub": "^0.14.0", + "@mdit/plugin-sup": "^0.14.0", + "@types/markdown-it": "^14.1.2", + "@vuepress/helper": "2.0.0-rc.66" + }, + "peerDependencies": { + "vuepress": "2.0.0-rc.19" + } + }, "node_modules/@vuepress/plugin-markdown-tab": { - "version": "2.0.0-rc.62", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-markdown-tab/-/plugin-markdown-tab-2.0.0-rc.62.tgz", - "integrity": "sha512-rjIZ5P6unPMcuLktVJlsqaU6VnrSa+n/phxCrWzZ4dBLUNjbDEqPB6YnrBgiO4dZzLeLVqpE2dqWMiuK0CbRjg==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-markdown-tab/-/plugin-markdown-tab-2.0.0-rc.66.tgz", + "integrity": "sha512-QpZAM8YuqVPzQRtEBne+MxDtrlrXQFhQe5xkL8FUvqdxAenQqb6IfK413rsay91tfLE88i9xcJSIjU3ikSl/Kg==", "dev": true, "dependencies": { "@mdit/plugin-tab": "^0.14.0", "@types/markdown-it": "^14.1.2", - "@vuepress/helper": "2.0.0-rc.62", + "@vuepress/helper": "2.0.0-rc.66", "@vueuse/core": "^12.0.0", "vue": "^3.5.13" }, "peerDependencies": { - "vuepress": "2.0.0-rc.18" + "vuepress": "2.0.0-rc.19" } }, "node_modules/@vuepress/plugin-markdown-tab/node_modules/@mdit/plugin-tab": { @@ -3231,166 +3070,106 @@ } } }, - "node_modules/@vuepress/plugin-markdown-tab/node_modules/@vuepress/helper": { - "version": "2.0.0-rc.62", - "resolved": "https://registry.npmjs.org/@vuepress/helper/-/helper-2.0.0-rc.62.tgz", - "integrity": "sha512-O6I9iliP1UxSI0g2PfLyx/WqvuKtGdcUl1DlxMQAw/YRfjbvcVIetV/htiUA3C8H5+RgJXvzRX/Zruik2aiuGg==", + "node_modules/@vuepress/plugin-notice": { + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-notice/-/plugin-notice-2.0.0-rc.66.tgz", + "integrity": "sha512-tYySrJYoX/RMGF7YmQSqKIttWnbtraCy0r5lr+8EmOsLxUwPJqD52rXKlfxaIjMGjGoyYx0WzUpy5Txm9PPPeg==", "dev": true, "dependencies": { - "@vue/shared": "^3.5.13", + "@vuepress/helper": "2.0.0-rc.66", "@vueuse/core": "^12.0.0", - "cheerio": "1.0.0", - "fflate": "^0.8.2", - "gray-matter": "^4.0.3", - "vue": "^3.5.13" - }, - "peerDependencies": { - "vuepress": "2.0.0-rc.18" - } - }, - "node_modules/@vuepress/plugin-markdown-tab/node_modules/@vueuse/core": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-12.0.0.tgz", - "integrity": "sha512-C12RukhXiJCbx4MGhjmd/gH52TjJsc3G0E0kQj/kb19H3Nt6n1CA4DRWuTdWWcaFRdlTe0npWDS942mvacvNBw==", - "dev": true, - "dependencies": { - "@types/web-bluetooth": "^0.0.20", - "@vueuse/metadata": "12.0.0", - "@vueuse/shared": "12.0.0", - "vue": "^3.5.13" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/@vuepress/plugin-markdown-tab/node_modules/@vueuse/metadata": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-12.0.0.tgz", - "integrity": "sha512-Yzimd1D3sjxTDOlF05HekU5aSGdKjxhuhRFHA7gDWLn57PRbBIh+SF5NmjhJ0WRgF3my7T8LBucyxdFJjIfRJQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/@vuepress/plugin-markdown-tab/node_modules/@vueuse/shared": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-12.0.0.tgz", - "integrity": "sha512-3i6qtcq2PIio5i/vVYidkkcgvmTjCqrf26u+Fd4LhnbBmIT6FN8y6q/GJERp8lfcB9zVEfjdV0Br0443qZuJpw==", - "dev": true, - "dependencies": { "vue": "^3.5.13" }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/@vuepress/plugin-notice": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-notice/-/plugin-notice-2.0.0-rc.56.tgz", - "integrity": "sha512-qSJ5PrGTVvRhSeyIXRz7cBFZ0nQ6J9tXSIsie7K31NuXDYqq6gOX6nT6uARvHgJwcX0ah9hcLovSVqJomkeSsA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vuepress/helper": "2.0.0-rc.56", - "@vueuse/core": "^11.1.0", - "vue": "^3.5.12" - }, "peerDependencies": { - "vuepress": "2.0.0-rc.18" + "vuepress": "2.0.0-rc.19" } }, "node_modules/@vuepress/plugin-nprogress": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-nprogress/-/plugin-nprogress-2.0.0-rc.56.tgz", - "integrity": "sha512-U0KxEvDDk5r2+B8SVsrEu7gFzz3vs8K5bVlUQiyEQ5vdE1aKIUjA/hQwq/gWy76qmOIVlHlKZnOB5C+w4At0SA==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-nprogress/-/plugin-nprogress-2.0.0-rc.66.tgz", + "integrity": "sha512-nVjZjxeeGbFk0AsugMX5Y2dgATfMTO0Hvb3JaOH1ee8H06Ia3A0eCYBwzOs/eP/F1lYx934PJS3aRqnkx2f+mg==", "dev": true, - "license": "MIT", "dependencies": { - "@vuepress/helper": "2.0.0-rc.56", - "vue": "^3.5.12" + "@vuepress/helper": "2.0.0-rc.66", + "vue": "^3.5.13" }, "peerDependencies": { - "vuepress": "2.0.0-rc.18" + "vuepress": "2.0.0-rc.19" } }, "node_modules/@vuepress/plugin-photo-swipe": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-photo-swipe/-/plugin-photo-swipe-2.0.0-rc.56.tgz", - "integrity": "sha512-/XBmWwmrrctO/M7AceFJLFMrjdpnDBPyKN1w/ecJr75AEPBYhntoXZdB+AOgRvHswhP2XUUiku6zrXx10zdO6g==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-photo-swipe/-/plugin-photo-swipe-2.0.0-rc.66.tgz", + "integrity": "sha512-lKF0yFYAJ6lhg6+/ud2CukOznMV3G8ZivZIAIG79YrM27FeFG0QznXVYdWmA/76sPu83gGQEQLFM6DyDHgkhEg==", "dev": true, - "license": "MIT", "dependencies": { - "@vuepress/helper": "2.0.0-rc.56", - "@vueuse/core": "^11.1.0", + "@vuepress/helper": "2.0.0-rc.66", + "@vueuse/core": "^12.0.0", "photoswipe": "^5.4.4", - "vue": "^3.5.12" + "vue": "^3.5.13" }, "peerDependencies": { - "vuepress": "2.0.0-rc.18" + "vuepress": "2.0.0-rc.19" } }, "node_modules/@vuepress/plugin-reading-time": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-reading-time/-/plugin-reading-time-2.0.0-rc.56.tgz", - "integrity": "sha512-69JJTZUd9lb2aq9VII19+Y9nPRjiRi0sclEboGpvy7P4JabPKu4AiLh1L/OPBzpXsxZuMmz+EDErOUozL3eSGw==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-reading-time/-/plugin-reading-time-2.0.0-rc.66.tgz", + "integrity": "sha512-42T9i+oqqCkBXlYmoEWEW0miX3Ypubyw+0OdOSEpKm3LioDnIL9l+GmgyBy2VRqin3foerNJCwDqUMoa2Jxb8w==", "dev": true, - "license": "MIT", "dependencies": { - "@vuepress/helper": "2.0.0-rc.56", - "vue": "^3.5.12" + "@vuepress/helper": "2.0.0-rc.66", + "vue": "^3.5.13" }, "peerDependencies": { - "vuepress": "2.0.0-rc.18" + "vuepress": "2.0.0-rc.19" } }, "node_modules/@vuepress/plugin-redirect": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-redirect/-/plugin-redirect-2.0.0-rc.56.tgz", - "integrity": "sha512-MmiZGMTQwCtdBGapII3u0iG8C9Y36eH15Pzt2G5Auwzp9X9LL/TLmuN2K0/ckjqkWj0j7ei6to4k0/TFEjSKbw==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-redirect/-/plugin-redirect-2.0.0-rc.66.tgz", + "integrity": "sha512-fY1R6NI7coEqeBaCyfV7ETZUymUnheykenDAvZJf90I62sWYBRd27sKYQWNpobOmXKqRzyx/WFyixbfiBYrWLQ==", "dev": true, - "license": "MIT", "dependencies": { - "@vuepress/helper": "2.0.0-rc.56", - "@vueuse/core": "^11.1.0", + "@vuepress/helper": "2.0.0-rc.66", + "@vueuse/core": "^12.0.0", "cac": "^6.7.14", - "vue": "^3.5.12" + "vue": "^3.5.13" }, "bin": { "vp-redirect": "lib/cli/index.js" }, "peerDependencies": { - "vuepress": "2.0.0-rc.18" + "vuepress": "2.0.0-rc.19" } }, "node_modules/@vuepress/plugin-rtl": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-rtl/-/plugin-rtl-2.0.0-rc.56.tgz", - "integrity": "sha512-qlN5FcIl1pdCjadqiYCy96zObZ18m6FyzEp22MPgZmvKYgHR5N2BPzV98wQYSICx0Fz1lYftQFgqNnmrCqB5OQ==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-rtl/-/plugin-rtl-2.0.0-rc.66.tgz", + "integrity": "sha512-OzIwtq/6a37qJXYsOMhqm0PZPRNgu0+CPnkjW71jPZlBaqyb7D6NJOCDuBncVyVDR8uC7OJbaCHT8otJvOWrig==", "dev": true, - "license": "MIT", "dependencies": { - "@vuepress/helper": "2.0.0-rc.56", - "vue": "^3.5.12" + "@vuepress/helper": "2.0.0-rc.66", + "vue": "^3.5.13" }, "peerDependencies": { - "vuepress": "2.0.0-rc.18" + "vuepress": "2.0.0-rc.19" } }, "node_modules/@vuepress/plugin-sass-palette": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-sass-palette/-/plugin-sass-palette-2.0.0-rc.56.tgz", - "integrity": "sha512-gGA/CidSaOGiuskWKPsUGFVgiv3xEZAQDMRUaAgeMdvObJ70/wYO09uPaTu56mesrpc9P+FBMH67sdTQfHietQ==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-sass-palette/-/plugin-sass-palette-2.0.0-rc.66.tgz", + "integrity": "sha512-ghMAGK+nRyLmTssppOYcF3N4hsVrM+4H88WKNM6u9QwGx0EyzC/tEEL0CE3QwgJMMt6FKVGsHwDC64Mz/j2a3g==", "dev": true, - "license": "MIT", "dependencies": { - "@vuepress/helper": "2.0.0-rc.56", + "@vuepress/helper": "2.0.0-rc.66", "chokidar": "^4.0.1" }, "peerDependencies": { "sass": "^1.80.3", "sass-embedded": "^1.80.3", "sass-loader": "^16.0.2", - "vuepress": "2.0.0-rc.18" + "vuepress": "2.0.0-rc.19" }, "peerDependenciesMeta": { "sass": { @@ -3409,7 +3188,6 @@ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz", "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==", "dev": true, - "license": "MIT", "dependencies": { "readdirp": "^4.0.1" }, @@ -3425,7 +3203,6 @@ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", "dev": true, - "license": "MIT", "engines": { "node": ">= 14.16.0" }, @@ -3435,39 +3212,37 @@ } }, "node_modules/@vuepress/plugin-seo": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-seo/-/plugin-seo-2.0.0-rc.56.tgz", - "integrity": "sha512-s1DyQA7umBlzPKbehiey5xk5w2ANlkifeYd26sj5ReRF8J6k0ZxdN6ahyBqxm9TPd8+69yW8GYZq0OXrh0qv9Q==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-seo/-/plugin-seo-2.0.0-rc.66.tgz", + "integrity": "sha512-DqOrTnF3r6RBlQvENRejYKGPcdOBXo7gzYha2NtRtgMzxPjCZM9oom6jd8ew1VLuM0JhDoLG9AfUjgnRVrpM0w==", "dev": true, - "license": "MIT", "dependencies": { - "@vuepress/helper": "2.0.0-rc.56" + "@vuepress/helper": "2.0.0-rc.66" }, "peerDependencies": { - "vuepress": "2.0.0-rc.18" + "vuepress": "2.0.0-rc.19" } }, "node_modules/@vuepress/plugin-shiki": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-shiki/-/plugin-shiki-2.0.0-rc.56.tgz", - "integrity": "sha512-IQHz7SVZ1zqqryBBqjPvNI32wub7JPsnSoR+X5VoQR4Ncs5i13+sOndZVHDUZMdpfwuKej50ZNW2SioTqN3ngA==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-shiki/-/plugin-shiki-2.0.0-rc.66.tgz", + "integrity": "sha512-yq54ry9P8/xQP/eUZvctko/zhGsTPLywhN538ttOospog0Lh8u/m9aNra3sRuGNHBOeF4oyKJ3VyQfb9gfHmZg==", "dev": true, - "license": "MIT", "dependencies": { - "@shikijs/transformers": "^1.22.0", - "@vuepress/helper": "2.0.0-rc.56", - "@vuepress/highlighter-helper": "2.0.0-rc.56", - "nanoid": "^5.0.7", - "shiki": "^1.22.0" + "@shikijs/transformers": "^1.24.2", + "@vuepress/helper": "2.0.0-rc.66", + "@vuepress/highlighter-helper": "2.0.0-rc.66", + "nanoid": "^5.0.9", + "shiki": "^1.24.2" }, "peerDependencies": { - "vuepress": "2.0.0-rc.18" + "vuepress": "2.0.0-rc.19" } }, "node_modules/@vuepress/plugin-shiki/node_modules/nanoid": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.7.tgz", - "integrity": "sha512-oLxFY2gd2IqnjcYyOXD8XGCftpGtZP2AbHbOkthDkvRywH5ayNtPVy9YlOPcHckXzbLTCHpkb7FB+yuxKV13pQ==", + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.9.tgz", + "integrity": "sha512-Aooyr6MXU6HpvvWXKoVoXwKMs/KyVakWwg7xQfv5/S/RIgJMy0Ifa45H9qqYy7pTCszrHzP21Uk4PZq2HpEM8Q==", "dev": true, "funding": [ { @@ -3475,7 +3250,6 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "bin": { "nanoid": "bin/nanoid.js" }, @@ -3484,174 +3258,116 @@ } }, "node_modules/@vuepress/plugin-sitemap": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-sitemap/-/plugin-sitemap-2.0.0-rc.56.tgz", - "integrity": "sha512-zEhsQQ5YSfdvywQxn9PhjzNB5QDOBT5/9wmUsuaBT/feDW6vII3OCoj/Z5+lz2kfmL67qjqswmqklF84v2PbRQ==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-sitemap/-/plugin-sitemap-2.0.0-rc.66.tgz", + "integrity": "sha512-1SbnuyUj/6CId4SDMCPlFEJPjNdXgcPZS+iWNLGiAe6NuTrMeFRSJ/huZDphtJnfL20TboVrMowExpzKR2GoAg==", "dev": true, - "license": "MIT", "dependencies": { - "@vuepress/helper": "2.0.0-rc.56", + "@vuepress/helper": "2.0.0-rc.66", "sitemap": "^8.0.0" }, "peerDependencies": { - "vuepress": "2.0.0-rc.18" + "vuepress": "2.0.0-rc.19" } }, "node_modules/@vuepress/plugin-theme-data": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-theme-data/-/plugin-theme-data-2.0.0-rc.56.tgz", - "integrity": "sha512-FccAdVbPxtXgdfOhCT1spNVDv/WfveTcDJ4FFZURf6YqJ9LflIhPpFIcRtE3XUD5HBEC4vvxuJCRxWOesM1LVQ==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-theme-data/-/plugin-theme-data-2.0.0-rc.66.tgz", + "integrity": "sha512-zCojGjYuQo/EXeF4cXA99ubxE7TUNDopMUGIjKKJjpDs1me6zkXSj1NqKnUD3+uHpP0PP7YXfROxTlk6Fy+FGg==", "dev": true, - "license": "MIT", "dependencies": { - "@vue/devtools-api": "^7.5.2", - "vue": "^3.5.12" + "@vue/devtools-api": "^7.6.8", + "vue": "^3.5.13" }, "peerDependencies": { - "vuepress": "2.0.0-rc.18" + "vuepress": "2.0.0-rc.19" } }, "node_modules/@vuepress/plugin-theme-data/node_modules/@vue/devtools-api": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.5.2.tgz", - "integrity": "sha512-VxPbAQxJrYSIkoGVvQ2oOoKW8u4CMpvRLySTxhoJA38z8bQEGy9GO33eoRY/DulJbSFRfjZFNvH+dh8B4qpesQ==", + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.6.8.tgz", + "integrity": "sha512-ma6dY/sZR36zALVsV1W7eC57c6IJPXsy8SNgZn1PLVWU4z4dPn5TIBmnF4stmdJ4sQcixqKaQ8pwjbMPzEZwiA==", "dev": true, - "license": "MIT", "dependencies": { - "@vue/devtools-kit": "^7.5.2" + "@vue/devtools-kit": "^7.6.8" } }, "node_modules/@vuepress/plugin-watermark": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-watermark/-/plugin-watermark-2.0.0-rc.56.tgz", - "integrity": "sha512-u2rWJhODTs++77e2mdrSRxUOD9qUMJZrhyhBjrXprfGfOmvo7CE54NoR8oznKxEa7JSfGaibDWVIqgHvOLlm7g==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-watermark/-/plugin-watermark-2.0.0-rc.66.tgz", + "integrity": "sha512-QaC7v/s/kUvO7rMzoyE3V4VPXDQarMUNEBVbSi4k/ghJxCyyO57GxlB2P+5ZLgp5P3frmecGd/BJ0lNUFPbR3g==", "dev": true, - "license": "MIT", "dependencies": { - "@vuepress/helper": "2.0.0-rc.56", - "vue": "^3.5.12", + "@vuepress/helper": "2.0.0-rc.66", + "vue": "^3.5.13", "watermark-js-plus": "^1.5.7" }, "peerDependencies": { - "vuepress": "2.0.0-rc.18" + "vuepress": "2.0.0-rc.19" } }, "node_modules/@vuepress/shared": { - "version": "2.0.0-rc.18", - "resolved": "https://registry.npmjs.org/@vuepress/shared/-/shared-2.0.0-rc.18.tgz", - "integrity": "sha512-um5/ZKGOKgaui5Xo1aRSZ3ko7zVq60k1M8j8ajEOu90LUD1e8glTa7Km9OIBgPcN+yx2OrNwuu8ieEupdNAm4w==", + "version": "2.0.0-rc.19", + "resolved": "https://registry.npmjs.org/@vuepress/shared/-/shared-2.0.0-rc.19.tgz", + "integrity": "sha512-xaDeZxX0Qetc2Y6/lrzO6M/40i3LmMm7Fk85bOftBBOaNehZ24RdsmIHBJDDv+bTUv+DBF++1/mOtbt6DBRzEA==", "dev": true, - "license": "MIT", "dependencies": { "@mdit-vue/types": "^2.1.0" } }, "node_modules/@vuepress/utils": { - "version": "2.0.0-rc.18", - "resolved": "https://registry.npmjs.org/@vuepress/utils/-/utils-2.0.0-rc.18.tgz", - "integrity": "sha512-0+5vrv3CBycWpAahmutEK2iyuc9oL6JOWMuAdh+cYuuHt1vX+LHfhWGvSep+UT6pOFGOcZfQzXSdlbkv3b4j+Q==", + "version": "2.0.0-rc.19", + "resolved": "https://registry.npmjs.org/@vuepress/utils/-/utils-2.0.0-rc.19.tgz", + "integrity": "sha512-cgzk8/aJquZKgFMNTuqdjbU5NrCzrPmdTyhYBcmliL/6N/He1OTWn3PD9QWUGJNODb1sPRJpklZnCpU07waLmg==", "dev": true, - "license": "MIT", "dependencies": { "@types/debug": "^4.1.12", "@types/fs-extra": "^11.0.4", "@types/hash-sum": "^1.0.2", - "@vuepress/shared": "2.0.0-rc.18", - "debug": "^4.3.7", + "@vuepress/shared": "2.0.0-rc.19", + "debug": "^4.4.0", "fs-extra": "^11.2.0", "globby": "^14.0.2", "hash-sum": "^2.0.0", - "ora": "^8.1.0", - "picocolors": "^1.1.0", + "ora": "^8.1.1", + "picocolors": "^1.1.1", "upath": "^2.0.1" } }, "node_modules/@vueuse/core": { - "version": "11.3.0", - "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-11.3.0.tgz", - "integrity": "sha512-7OC4Rl1f9G8IT6rUfi9JrKiXy4bfmHhZ5x2Ceojy0jnd3mHNEvV4JaRygH362ror6/NZ+Nl+n13LPzGiPN8cKA==", + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-12.0.0.tgz", + "integrity": "sha512-C12RukhXiJCbx4MGhjmd/gH52TjJsc3G0E0kQj/kb19H3Nt6n1CA4DRWuTdWWcaFRdlTe0npWDS942mvacvNBw==", "dev": true, "dependencies": { "@types/web-bluetooth": "^0.0.20", - "@vueuse/metadata": "11.3.0", - "@vueuse/shared": "11.3.0", - "vue-demi": ">=0.14.10" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/@vueuse/core/node_modules/vue-demi": { - "version": "0.14.10", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz", - "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", - "dev": true, - "hasInstallScript": true, - "bin": { - "vue-demi-fix": "bin/vue-demi-fix.js", - "vue-demi-switch": "bin/vue-demi-switch.js" - }, - "engines": { - "node": ">=12" + "@vueuse/metadata": "12.0.0", + "@vueuse/shared": "12.0.0", + "vue": "^3.5.13" }, "funding": { "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "@vue/composition-api": "^1.0.0-rc.1", - "vue": "^3.0.0-0 || ^2.6.0" - }, - "peerDependenciesMeta": { - "@vue/composition-api": { - "optional": true - } } }, "node_modules/@vueuse/metadata": { - "version": "11.3.0", - "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-11.3.0.tgz", - "integrity": "sha512-pwDnDspTqtTo2HwfLw4Rp6yywuuBdYnPYDq+mO38ZYKGebCUQC/nVj/PXSiK9HX5otxLz8Fn7ECPbjiRz2CC3g==", + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-12.0.0.tgz", + "integrity": "sha512-Yzimd1D3sjxTDOlF05HekU5aSGdKjxhuhRFHA7gDWLn57PRbBIh+SF5NmjhJ0WRgF3my7T8LBucyxdFJjIfRJQ==", "dev": true, "funding": { "url": "https://github.com/sponsors/antfu" } }, "node_modules/@vueuse/shared": { - "version": "11.3.0", - "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-11.3.0.tgz", - "integrity": "sha512-P8gSSWQeucH5821ek2mn/ciCk+MS/zoRKqdQIM3bHq6p7GXDAJLmnRRKmF5F65sAVJIfzQlwR3aDzwCn10s8hA==", + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-12.0.0.tgz", + "integrity": "sha512-3i6qtcq2PIio5i/vVYidkkcgvmTjCqrf26u+Fd4LhnbBmIT6FN8y6q/GJERp8lfcB9zVEfjdV0Br0443qZuJpw==", "dev": true, "dependencies": { - "vue-demi": ">=0.14.10" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/@vueuse/shared/node_modules/vue-demi": { - "version": "0.14.10", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz", - "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", - "dev": true, - "hasInstallScript": true, - "bin": { - "vue-demi-fix": "bin/vue-demi-fix.js", - "vue-demi-switch": "bin/vue-demi-switch.js" - }, - "engines": { - "node": ">=12" + "vue": "^3.5.13" }, "funding": { "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "@vue/composition-api": "^1.0.0-rc.1", - "vue": "^3.0.0-0 || ^2.6.0" - }, - "peerDependenciesMeta": { - "@vue/composition-api": { - "optional": true - } } }, "node_modules/acorn": { @@ -3929,9 +3645,9 @@ } }, "node_modules/bcrypt-ts": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-ts/-/bcrypt-ts-5.0.2.tgz", - "integrity": "sha512-gDwQ5784AkkfhHACh3jGcg1hUubyZyeq9AtVd5gXkcyHGVOC+mORjRIHSj+fHfqwY5vxwyBLXQpcfk8MpK0ROg==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/bcrypt-ts/-/bcrypt-ts-5.0.3.tgz", + "integrity": "sha512-2FcgD12xPbwCoe5i9/HK0jJ1xA1m+QfC1e6htG9Bl/hNOnLyaFmQSlqLKcfe3QdnoMPKpKEGFCbESBTg+SJNOw==", "dev": true, "engines": { "node": ">=18" @@ -3954,7 +3670,6 @@ "resolved": "https://registry.npmjs.org/birpc/-/birpc-0.2.19.tgz", "integrity": "sha512-5WeXXAvTmitV1RqJFppT5QtUiz2p1mRSYU000Jkft5ZUCLJIk4uQriYNO50HknxKwM6jd8utNc66K1qGIwwWBQ==", "dev": true, - "license": "MIT", "funding": { "url": "https://github.com/sponsors/antfu" } @@ -4055,14 +3770,6 @@ "node": "*" } }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true, - "optional": true, - "peer": true - }, "node_modules/cac": { "version": "6.7.14", "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", @@ -4106,7 +3813,6 @@ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } @@ -4142,7 +3848,6 @@ "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", "dev": true, - "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -4181,7 +3886,6 @@ "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", "dev": true, - "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -4192,7 +3896,6 @@ "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", "dev": true, - "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -4386,7 +4089,6 @@ "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", "dev": true, - "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", @@ -4398,7 +4100,6 @@ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -4449,7 +4150,6 @@ "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", "dev": true, - "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -4493,7 +4193,6 @@ "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz", "integrity": "sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==", "dev": true, - "license": "MIT", "dependencies": { "is-what": "^4.1.8" }, @@ -4524,7 +4223,6 @@ "resolved": "https://registry.npmjs.org/create-codepen/-/create-codepen-2.0.0.tgz", "integrity": "sha512-ehJ0Zw5RSV2G4+/azUb7vEZWRSA/K9cW7HDock1Y9ViDexkgSJUZJRcObdw/YAWeXKjreEQV9l/igNSsJ1yw5A==", "dev": true, - "license": "MIT", "engines": { "node": ">=18" } @@ -5206,7 +4904,6 @@ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -5251,7 +4948,6 @@ "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } @@ -5275,7 +4971,6 @@ "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", "dev": true, - "license": "MIT", "dependencies": { "dequal": "^2.0.0" }, @@ -5288,8 +4983,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.3.tgz", "integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/dom-serializer": { "version": "2.0.0", @@ -5387,6 +5081,12 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "node_modules/emoji-regex-xs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex-xs/-/emoji-regex-xs-1.0.0.tgz", + "integrity": "sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==", + "dev": true + }, "node_modules/encoding-sniffer": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.0.tgz", @@ -5440,7 +5140,6 @@ "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.14.0.tgz", "integrity": "sha512-CO40UI41xDQzhLB1hWyqUKgFhs250pNcGbyGKe1l/e4FSaI/+YE4IMG76GDt0In67WLPACIITC+sOi08x4wIvg==", "dev": true, - "license": "MIT", "bin": { "envinfo": "dist/cli.js" }, @@ -5730,7 +5429,6 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, - "license": "MIT", "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -5858,7 +5556,6 @@ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, - "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } @@ -5933,7 +5630,6 @@ "resolved": "https://registry.npmjs.org/giscus/-/giscus-1.5.0.tgz", "integrity": "sha512-t3LL0qbSO3JXq3uyQeKpF5CegstGfKX/0gI6eDe1cmnI7D56R7j52yLdzw4pdKrg3VnufwCgCM3FDz7G1Qr6lg==", "dev": true, - "license": "MIT", "dependencies": { "lit": "^3.1.2" } @@ -6091,11 +5787,10 @@ } }, "node_modules/hast-util-to-html": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.3.tgz", - "integrity": "sha512-M17uBDzMJ9RPCqLMO92gNNUDuBSq10a25SDBI08iCCxmorf4Yy6sYHK57n9WAbRAAaU+DuR4W6GN9K4DFZesYg==", + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.4.tgz", + "integrity": "sha512-wxQzXtdbhiwGAUKrnQJXlOPmHnEehzphwkK7aluUPQ+lEc1xefC8pblMgpp2w5ldBTEfveRIrADcrhGIWrlTDA==", "dev": true, - "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", @@ -6119,7 +5814,6 @@ "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", "dev": true, - "license": "MIT", "dependencies": { "@types/hast": "^3.0.0" }, @@ -6132,15 +5826,13 @@ "version": "5.5.3", "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz", "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/html-void-elements": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", "dev": true, - "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -6233,9 +5925,9 @@ } }, "node_modules/immutable": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz", - "integrity": "sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.0.3.tgz", + "integrity": "sha512-P8IdPQHq3lA1xVeBRi5VPqUm5HDgKnx0Ru51wZz5mjxHr5n3RWhjIpOFU7ybkUxfB+5IToy+OLaHYDBIWsv+uw==", "dev": true, "optional": true, "peer": true @@ -6371,7 +6063,6 @@ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", "dev": true, - "license": "MIT", "engines": { "node": ">=12" }, @@ -6414,7 +6105,6 @@ "resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.16.tgz", "integrity": "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==", "dev": true, - "license": "MIT", "engines": { "node": ">=12.13" }, @@ -6595,246 +6285,6 @@ "node": "> 0.8" } }, - "node_modules/lightningcss": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.27.0.tgz", - "integrity": "sha512-8f7aNmS1+etYSLHht0fQApPc2kNO8qGRutifN5rVIc6Xo6ABsEbqOr758UwI7ALVbTt4x1fllKt0PYgzD9S3yQ==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "detect-libc": "^1.0.3" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "optionalDependencies": { - "lightningcss-darwin-arm64": "1.27.0", - "lightningcss-darwin-x64": "1.27.0", - "lightningcss-freebsd-x64": "1.27.0", - "lightningcss-linux-arm-gnueabihf": "1.27.0", - "lightningcss-linux-arm64-gnu": "1.27.0", - "lightningcss-linux-arm64-musl": "1.27.0", - "lightningcss-linux-x64-gnu": "1.27.0", - "lightningcss-linux-x64-musl": "1.27.0", - "lightningcss-win32-arm64-msvc": "1.27.0", - "lightningcss-win32-x64-msvc": "1.27.0" - } - }, - "node_modules/lightningcss-darwin-arm64": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.27.0.tgz", - "integrity": "sha512-Gl/lqIXY+d+ySmMbgDf0pgaWSqrWYxVHoc88q+Vhf2YNzZ8DwoRzGt5NZDVqqIW5ScpSnmmjcgXP87Dn2ylSSQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "peer": true, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-darwin-x64": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.27.0.tgz", - "integrity": "sha512-0+mZa54IlcNAoQS9E0+niovhyjjQWEMrwW0p2sSdLRhLDc8LMQ/b67z7+B5q4VmjYCMSfnFi3djAAQFIDuj/Tg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "peer": true, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-freebsd-x64": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.27.0.tgz", - "integrity": "sha512-n1sEf85fePoU2aDN2PzYjoI8gbBqnmLGEhKq7q0DKLj0UTVmOTwDC7PtLcy/zFxzASTSBlVQYJUhwIStQMIpRA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "peer": true, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.27.0.tgz", - "integrity": "sha512-MUMRmtdRkOkd5z3h986HOuNBD1c2lq2BSQA1Jg88d9I7bmPGx08bwGcnB75dvr17CwxjxD6XPi3Qh8ArmKFqCA==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.27.0.tgz", - "integrity": "sha512-cPsxo1QEWq2sfKkSq2Bq5feQDHdUEwgtA9KaB27J5AX22+l4l0ptgjMZZtYtUnteBofjee+0oW1wQ1guv04a7A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.27.0.tgz", - "integrity": "sha512-rCGBm2ax7kQ9pBSeITfCW9XSVF69VX+fm5DIpvDZQl4NnQoMQyRwhZQm9pd59m8leZ1IesRqWk2v/DntMo26lg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.27.0.tgz", - "integrity": "sha512-Dk/jovSI7qqhJDiUibvaikNKI2x6kWPN79AQiD/E/KeQWMjdGe9kw51RAgoWFDi0coP4jinaH14Nrt/J8z3U4A==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-musl": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.27.0.tgz", - "integrity": "sha512-QKjTxXm8A9s6v9Tg3Fk0gscCQA1t/HMoF7Woy1u68wCk5kS4fR+q3vXa1p3++REW784cRAtkYKrPy6JKibrEZA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.27.0.tgz", - "integrity": "sha512-/wXegPS1hnhkeG4OXQKEMQeJd48RDC3qdh+OA8pCuOPCyvnm/yEayrJdJVqzBsqpy1aJklRCVxscpFur80o6iQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "peer": true, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.27.0.tgz", - "integrity": "sha512-/OJLj94Zm/waZShL8nB5jsNj3CfNATLCTyFxZyouilfTmSoLDX7VlVAmhPHoZWVFp4vdmoiEbPEYC8HID3m6yw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "peer": true, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, "node_modules/lilconfig": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", @@ -6888,7 +6338,6 @@ "resolved": "https://registry.npmjs.org/lit/-/lit-3.2.1.tgz", "integrity": "sha512-1BBa1E/z0O9ye5fZprPtdqnc0BFzxIxTTOO/tQFmyC/hj1O3jL4TfmLBw0WEwjAokdLwpclkvGgDJwTIh0/22w==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "@lit/reactive-element": "^2.0.4", "lit-element": "^4.1.0", @@ -6900,7 +6349,6 @@ "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.1.1.tgz", "integrity": "sha512-HO9Tkkh34QkTeUmEdNYhMT8hzLid7YlMlATSi1q4q17HE5d9mrrEHJ/o8O2D0cMi182zK1F3v7x0PWFjrhXFew==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "@lit-labs/ssr-dom-shim": "^1.2.0", "@lit/reactive-element": "^2.0.4", @@ -6912,7 +6360,6 @@ "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.2.1.tgz", "integrity": "sha512-qI/3lziaPMSKsrwlxH/xMgikhQ0EGOX2ICU73Bi/YHFvz2j/yMCIrw4+puF2IpQ4+upd3EWbvnHM9+PnJn48YA==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "@types/trusted-types": "^2.0.2" } @@ -6938,7 +6385,6 @@ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, - "license": "MIT", "dependencies": { "p-locate": "^4.1.0" }, @@ -7066,7 +6512,6 @@ "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-9.2.0.tgz", "integrity": "sha512-sa2ErMQ6kKOA4l31gLGYliFQrMKkqSO0ZJgGhDHKijPf0pNFM9vghjAh3gn26pS4JDRs7Iwa9S36gxm3vgZTzg==", "dev": true, - "license": "Unlicense", "peerDependencies": { "@types/markdown-it": "*", "markdown-it": "*" @@ -7076,8 +6521,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/markdown-it-emoji/-/markdown-it-emoji-3.0.0.tgz", "integrity": "sha512-+rUD93bXHubA4arpEZO3q80so0qgoFJEKRkRbjKX8RTdca89v2kfyF+xR3i2sQTwql9tpPZPOQN5B+PunspXRg==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/markdown-it/node_modules/argparse": { "version": "2.0.1", @@ -7102,7 +6546,6 @@ "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", "dev": true, - "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", @@ -7183,9 +6626,9 @@ } }, "node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "dev": true, "funding": [ { @@ -7197,16 +6640,15 @@ "url": "https://opencollective.com/unified" } ], - "license": "MIT", "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "node_modules/micromark-util-encode": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", - "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", "dev": true, "funding": [ { @@ -7217,13 +6659,12 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ], - "license": "MIT" + ] }, "node_modules/micromark-util-sanitize-uri": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", - "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", "dev": true, "funding": [ { @@ -7235,7 +6676,6 @@ "url": "https://opencollective.com/unified" } ], - "license": "MIT", "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-encode": "^2.0.0", @@ -7243,9 +6683,9 @@ } }, "node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "dev": true, "funding": [ { @@ -7256,13 +6696,12 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ], - "license": "MIT" + ] }, "node_modules/micromark-util-types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", - "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.1.tgz", + "integrity": "sha512-534m2WhVTddrcKVepwmVEVnUAmtrx9bfIjNoQHRqfnvdaHQiFytEhJoTgpWJvDEXCO5gLTQh3wYC1PgOJA4NSQ==", "dev": true, "funding": [ { @@ -7273,8 +6712,7 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ], - "license": "MIT" + ] }, "node_modules/micromatch": { "version": "4.0.8", @@ -7346,8 +6784,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/mlly": { "version": "1.7.1", @@ -7479,25 +6916,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/oniguruma-to-js": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/oniguruma-to-js/-/oniguruma-to-js-0.4.3.tgz", - "integrity": "sha512-X0jWUcAlxORhOqqBREgPMgnshB7ZGYszBNspP+tS9hPD3l13CdaXcHbgImoHUHlrvGx/7AvFEkTRhAGYh+jzjQ==", + "node_modules/oniguruma-to-es": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-0.7.0.tgz", + "integrity": "sha512-HRaRh09cE0gRS3+wi2zxekB+I5L8C/gN60S+vb11eADHUaB/q4u8wGGOX3GvwvitG8ixaeycZfeoyruKQzUgNg==", "dev": true, - "license": "MIT", "dependencies": { - "regex": "^4.3.2" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" + "emoji-regex-xs": "^1.0.0", + "regex": "^5.0.2", + "regex-recursion": "^4.3.0" } }, "node_modules/ora": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/ora/-/ora-8.1.0.tgz", - "integrity": "sha512-GQEkNkH/GHOhPFXcqZs3IDahXEQcQxsSjEkK4KvEEST4t7eNzoMjxTzef+EZ+JluDEV+Raoi3WQ2CflnRdSVnQ==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-8.1.1.tgz", + "integrity": "sha512-YWielGi1XzG1UTvOaCFaNgEnuhZVMSHYkW/FQ7UX8O26PtlpdM84c0f7wLPlkvx2RfiQmnzd61d/MGxmpQeJPw==", "dev": true, - "license": "MIT", "dependencies": { "chalk": "^5.3.0", "cli-cursor": "^5.0.0", @@ -7699,7 +7133,6 @@ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, - "license": "MIT", "dependencies": { "p-try": "^2.0.0" }, @@ -7715,7 +7148,6 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, - "license": "MIT", "dependencies": { "p-limit": "^2.2.0" }, @@ -7743,7 +7175,6 @@ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } @@ -7759,7 +7190,6 @@ "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz", "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==", "dev": true, - "license": "MIT", "engines": { "node": ">=18" }, @@ -7818,7 +7248,6 @@ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } @@ -7870,8 +7299,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz", "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/performance-now": { "version": "2.1.0", @@ -7884,7 +7312,6 @@ "resolved": "https://registry.npmjs.org/photoswipe/-/photoswipe-5.4.4.tgz", "integrity": "sha512-WNFHoKrkZNnvFFhbHL93WDkW3ifwVOXSW3w1UuZZelSmgXpIGiZSNlZJq37rR8YejqME2rHs9EhH9ZvlvFH2NA==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.12.0" } @@ -7932,7 +7359,6 @@ "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz", "integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==", "dev": true, - "license": "MIT", "engines": { "node": ">=10.13.0" } @@ -8042,11 +7468,10 @@ } }, "node_modules/pretty-ms": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.1.0.tgz", - "integrity": "sha512-o1piW0n3tgKIKCwk2vpM/vOV13zjJzvP37Ioze54YlTHE06m4tjEbzg9WsKkvTuyYln2DHjo5pY4qrZGI0otpw==", + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.2.0.tgz", + "integrity": "sha512-4yf0QO/sllf/1zbZWYnvWw3NxCQwLXKzIj0G849LSufP15BXKM0rbD2Z3wVnkMfjdn/CB0Dpp444gYAACdsplg==", "dev": true, - "license": "MIT", "dependencies": { "parse-ms": "^4.0.0" }, @@ -8071,7 +7496,6 @@ "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz", "integrity": "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==", "dev": true, - "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -8122,7 +7546,6 @@ "resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.4.tgz", "integrity": "sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==", "dev": true, - "license": "MIT", "dependencies": { "dijkstrajs": "^1.0.1", "pngjs": "^5.0.0", @@ -8193,11 +7616,28 @@ } }, "node_modules/regex": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/regex/-/regex-4.3.3.tgz", - "integrity": "sha512-r/AadFO7owAq1QJVeZ/nq9jNS1vyZt+6t1p/E59B56Rn2GCya+gr1KSyOzNL/er+r+B7phv5jG2xU2Nz1YkmJg==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/regex/-/regex-5.0.2.tgz", + "integrity": "sha512-/pczGbKIQgfTMRV0XjABvc5RzLqQmwqxLHdQao2RTXPk+pmTXB2P0IaUHYdYyk412YLwUIkaeMd5T+RzVgTqnQ==", "dev": true, - "license": "MIT" + "dependencies": { + "regex-utilities": "^2.3.0" + } + }, + "node_modules/regex-recursion": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/regex-recursion/-/regex-recursion-4.3.0.tgz", + "integrity": "sha512-5LcLnizwjcQ2ALfOj95MjcatxyqF5RPySx9yT+PaXu3Gox2vyAtLDjHB8NTJLtMGkvyau6nI3CfpwFCjPUIs/A==", + "dev": true, + "dependencies": { + "regex-utilities": "^2.3.0" + } + }, + "node_modules/regex-utilities": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/regex-utilities/-/regex-utilities-2.3.0.tgz", + "integrity": "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==", + "dev": true }, "node_modules/request-progress": { "version": "3.0.0", @@ -8213,7 +7653,6 @@ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -8222,8 +7661,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true, - "license": "ISC" + "dev": true }, "node_modules/restore-cursor": { "version": "3.1.0", @@ -8262,9 +7700,9 @@ "dev": true }, "node_modules/rollup": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.0.tgz", - "integrity": "sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.28.1.tgz", + "integrity": "sha512-61fXYl/qNVinKmGSTHAZ6Yy8I3YIJC/r2m9feHo6SwVAVcLT5MPwOUFe7EuURA/4m0NR8lXG4BBXuo/IZEsjMg==", "dev": true, "dependencies": { "@types/estree": "1.0.6" @@ -8277,22 +7715,25 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.24.0", - "@rollup/rollup-android-arm64": "4.24.0", - "@rollup/rollup-darwin-arm64": "4.24.0", - "@rollup/rollup-darwin-x64": "4.24.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.24.0", - "@rollup/rollup-linux-arm-musleabihf": "4.24.0", - "@rollup/rollup-linux-arm64-gnu": "4.24.0", - "@rollup/rollup-linux-arm64-musl": "4.24.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.24.0", - "@rollup/rollup-linux-riscv64-gnu": "4.24.0", - "@rollup/rollup-linux-s390x-gnu": "4.24.0", - "@rollup/rollup-linux-x64-gnu": "4.24.0", - "@rollup/rollup-linux-x64-musl": "4.24.0", - "@rollup/rollup-win32-arm64-msvc": "4.24.0", - "@rollup/rollup-win32-ia32-msvc": "4.24.0", - "@rollup/rollup-win32-x64-msvc": "4.24.0", + "@rollup/rollup-android-arm-eabi": "4.28.1", + "@rollup/rollup-android-arm64": "4.28.1", + "@rollup/rollup-darwin-arm64": "4.28.1", + "@rollup/rollup-darwin-x64": "4.28.1", + "@rollup/rollup-freebsd-arm64": "4.28.1", + "@rollup/rollup-freebsd-x64": "4.28.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.28.1", + "@rollup/rollup-linux-arm-musleabihf": "4.28.1", + "@rollup/rollup-linux-arm64-gnu": "4.28.1", + "@rollup/rollup-linux-arm64-musl": "4.28.1", + "@rollup/rollup-linux-loongarch64-gnu": "4.28.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.28.1", + "@rollup/rollup-linux-riscv64-gnu": "4.28.1", + "@rollup/rollup-linux-s390x-gnu": "4.28.1", + "@rollup/rollup-linux-x64-gnu": "4.28.1", + "@rollup/rollup-linux-x64-musl": "4.28.1", + "@rollup/rollup-win32-arm64-msvc": "4.28.1", + "@rollup/rollup-win32-ia32-msvc": "4.28.1", + "@rollup/rollup-win32-x64-msvc": "4.28.1", "fsevents": "~2.3.2" } }, @@ -8374,17 +7815,15 @@ "dev": true }, "node_modules/sass": { - "version": "1.80.3", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.80.3.tgz", - "integrity": "sha512-ptDWyVmDMVielpz/oWy3YP3nfs7LpJTHIJZboMVs8GEC9eUmtZTZhMHlTW98wY4aEorDfjN38+Wr/XjskFWcfA==", + "version": "1.83.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.83.0.tgz", + "integrity": "sha512-qsSxlayzoOjdvXMVLkzF84DJFc2HZEL/rFyGIKbbilYtAvlCxyuzUeff9LawTn4btVnLKg75Z8MMr1lxU1lfGw==", "dev": true, - "license": "MIT", "optional": true, "peer": true, "dependencies": { - "@parcel/watcher": "^2.4.1", "chokidar": "^4.0.0", - "immutable": "^4.0.0", + "immutable": "^5.0.2", "source-map-js": ">=0.6.2 <2.0.0" }, "bin": { @@ -8392,6 +7831,9 @@ }, "engines": { "node": ">=14.0.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" } }, "node_modules/sass/node_modules/chokidar": { @@ -8430,8 +7872,7 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", - "dev": true, - "license": "ISC" + "dev": true }, "node_modules/section-matter": { "version": "1.0.0", @@ -8463,8 +7904,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true, - "license": "ISC" + "dev": true }, "node_modules/set-function-length": { "version": "1.2.2", @@ -8505,16 +7945,15 @@ } }, "node_modules/shiki": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.22.0.tgz", - "integrity": "sha512-/t5LlhNs+UOKQCYBtl5ZsH/Vclz73GIqT2yQsCBygr8L/ppTdmpL4w3kPLoZJbMKVWtoG77Ue1feOjZfDxvMkw==", + "version": "1.24.2", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.24.2.tgz", + "integrity": "sha512-TR1fi6mkRrzW+SKT5G6uKuc32Dj2EEa7Kj0k8kGqiBINb+C1TiflVOiT9ta6GqOJtC4fraxO5SLUaKBcSY38Fg==", "dev": true, - "license": "MIT", "dependencies": { - "@shikijs/core": "1.22.0", - "@shikijs/engine-javascript": "1.22.0", - "@shikijs/engine-oniguruma": "1.22.0", - "@shikijs/types": "1.22.0", + "@shikijs/core": "1.24.2", + "@shikijs/engine-javascript": "1.24.2", + "@shikijs/engine-oniguruma": "1.24.2", + "@shikijs/types": "1.24.2", "@shikijs/vscode-textmate": "^9.3.0", "@types/hast": "^3.0.4" } @@ -8548,7 +7987,6 @@ "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-8.0.0.tgz", "integrity": "sha512-+AbdxhM9kJsHtruUF39bwS/B0Fytw6Fr1o4ZAIAEqA6cke2xcoO2GleBw9Zw7nRzILVEgz7zBM5GiTJjie1G9A==", "dev": true, - "license": "MIT", "dependencies": { "@types/node": "^17.0.5", "@types/sax": "^1.2.1", @@ -8567,8 +8005,7 @@ "version": "17.0.45", "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/slash": { "version": "5.1.0", @@ -8597,17 +8034,6 @@ "node": ">=8" } }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "optional": true, - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -8617,24 +8043,11 @@ "node": ">=0.10.0" } }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, "node_modules/space-separated-tokens": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", "dev": true, - "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -8645,7 +8058,6 @@ "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz", "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==", "dev": true, - "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -8803,7 +8215,6 @@ "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", "dev": true, - "license": "MIT", "dependencies": { "character-entities-html4": "^2.0.0", "character-entities-legacy": "^3.0.0" @@ -8851,11 +8262,10 @@ "dev": true }, "node_modules/superjson": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.1.tgz", - "integrity": "sha512-8iGv75BYOa0xRJHK5vRLEjE2H/i4lulTjzpUXic3Eg8akftYjkmQDa8JARQ42rlczXyFR3IeRoeFCc7RxHsYZA==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.2.tgz", + "integrity": "sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==", "dev": true, - "license": "MIT", "dependencies": { "copy-anything": "^3.0.2" }, @@ -8878,34 +8288,6 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/terser": { - "version": "5.31.6", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.6.tgz", - "integrity": "sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/terser/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true, - "optional": true, - "peer": true - }, "node_modules/throttleit": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.1.tgz", @@ -8992,7 +8374,6 @@ "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", "dev": true, - "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -9089,7 +8470,6 @@ "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", "dev": true, - "license": "MIT", "dependencies": { "@types/unist": "^3.0.0" }, @@ -9103,7 +8483,6 @@ "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", "dev": true, - "license": "MIT", "dependencies": { "@types/unist": "^3.0.0" }, @@ -9117,7 +8496,6 @@ "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", "dev": true, - "license": "MIT", "dependencies": { "@types/unist": "^3.0.0" }, @@ -9131,7 +8509,6 @@ "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", "dev": true, - "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", @@ -9147,7 +8524,6 @@ "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", "dev": true, - "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" @@ -9244,7 +8620,6 @@ "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", "dev": true, - "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", "vfile-message": "^4.0.0" @@ -9259,7 +8634,6 @@ "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", "dev": true, - "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" @@ -9270,62 +8644,481 @@ } }, "node_modules/vite": { - "version": "5.4.8", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.8.tgz", - "integrity": "sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.0.3.tgz", + "integrity": "sha512-Cmuo5P0ENTN6HxLSo6IHsjCLn/81Vgrp81oaiFFMRa8gGDj5xEjIcEpf2ZymZtZR8oU0P2JX5WuUp/rlXcHkAw==", "dev": true, "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.43", - "rollup": "^4.20.0" + "esbuild": "^0.24.0", + "postcss": "^8.4.49", + "rollup": "^4.23.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/@esbuild/aix-ppc64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.0.tgz", + "integrity": "sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.0.tgz", + "integrity": "sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.0.tgz", + "integrity": "sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/android-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.0.tgz", + "integrity": "sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.0.tgz", + "integrity": "sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.0.tgz", + "integrity": "sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.0.tgz", + "integrity": "sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.0.tgz", + "integrity": "sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.0.tgz", + "integrity": "sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.0.tgz", + "integrity": "sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ia32": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.0.tgz", + "integrity": "sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-loong64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.0.tgz", + "integrity": "sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-mips64el": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.0.tgz", + "integrity": "sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ppc64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.0.tgz", + "integrity": "sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-riscv64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.0.tgz", + "integrity": "sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-s390x": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.0.tgz", + "integrity": "sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.0.tgz", + "integrity": "sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/netbsd-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.0.tgz", + "integrity": "sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/openbsd-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.0.tgz", + "integrity": "sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/sunos-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.0.tgz", + "integrity": "sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.0.tgz", + "integrity": "sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-ia32": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.0.tgz", + "integrity": "sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.0.tgz", + "integrity": "sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/esbuild": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.0.tgz", + "integrity": "sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==", + "dev": true, + "hasInstallScript": true, "bin": { - "vite": "bin/vite.js" + "esbuild": "bin/esbuild" }, "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" + "node": ">=18" }, "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } + "@esbuild/aix-ppc64": "0.24.0", + "@esbuild/android-arm": "0.24.0", + "@esbuild/android-arm64": "0.24.0", + "@esbuild/android-x64": "0.24.0", + "@esbuild/darwin-arm64": "0.24.0", + "@esbuild/darwin-x64": "0.24.0", + "@esbuild/freebsd-arm64": "0.24.0", + "@esbuild/freebsd-x64": "0.24.0", + "@esbuild/linux-arm": "0.24.0", + "@esbuild/linux-arm64": "0.24.0", + "@esbuild/linux-ia32": "0.24.0", + "@esbuild/linux-loong64": "0.24.0", + "@esbuild/linux-mips64el": "0.24.0", + "@esbuild/linux-ppc64": "0.24.0", + "@esbuild/linux-riscv64": "0.24.0", + "@esbuild/linux-s390x": "0.24.0", + "@esbuild/linux-x64": "0.24.0", + "@esbuild/netbsd-x64": "0.24.0", + "@esbuild/openbsd-arm64": "0.24.0", + "@esbuild/openbsd-x64": "0.24.0", + "@esbuild/sunos-x64": "0.24.0", + "@esbuild/win32-arm64": "0.24.0", + "@esbuild/win32-ia32": "0.24.0", + "@esbuild/win32-x64": "0.24.0" } }, "node_modules/vscode-jsonrpc": { @@ -9399,9 +9192,9 @@ } }, "node_modules/vue-router": { - "version": "4.4.5", - "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.4.5.tgz", - "integrity": "sha512-4fKZygS8cH1yCyuabAXGUAsyi1b2/o/OKgu/RUb+znIYOxPRxdkytJEx+0wGcpBE1pX6vUgh5jwWOKRGvuA/7Q==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.5.0.tgz", + "integrity": "sha512-HDuk+PuH5monfNuY+ct49mNmkCRK4xJAV9Ts4z9UFc4rzdDnxQLyCMGGc8pKhZhHTVzfanpNwB/lwqevcBwI4w==", "dev": true, "dependencies": { "@vue/devtools-api": "^6.6.4" @@ -9414,19 +9207,18 @@ } }, "node_modules/vuepress": { - "version": "2.0.0-rc.18", - "resolved": "https://registry.npmjs.org/vuepress/-/vuepress-2.0.0-rc.18.tgz", - "integrity": "sha512-TFpePHTIMiUbiJcHTgD4Wc5eBlsxBnhv36F/eM2vbDoeutcS1dGrNtZoKUxrZDXTeZH+q8vrZ3CiBCsHw3K7eA==", + "version": "2.0.0-rc.19", + "resolved": "https://registry.npmjs.org/vuepress/-/vuepress-2.0.0-rc.19.tgz", + "integrity": "sha512-JDeuPTu14Kprdqx2geAryjFJvUzVaMnOLewlAgwVuZTygDWb8cgXhu9/p6rqzzdHETtIrvjbASBhH7JPyqmxmA==", "dev": true, - "license": "MIT", "dependencies": { - "@vuepress/cli": "2.0.0-rc.18", - "@vuepress/client": "2.0.0-rc.18", - "@vuepress/core": "2.0.0-rc.18", - "@vuepress/markdown": "2.0.0-rc.18", - "@vuepress/shared": "2.0.0-rc.18", - "@vuepress/utils": "2.0.0-rc.18", - "vue": "^3.5.11" + "@vuepress/cli": "2.0.0-rc.19", + "@vuepress/client": "2.0.0-rc.19", + "@vuepress/core": "2.0.0-rc.19", + "@vuepress/markdown": "2.0.0-rc.19", + "@vuepress/shared": "2.0.0-rc.19", + "@vuepress/utils": "2.0.0-rc.19", + "vue": "^3.5.13" }, "bin": { "vuepress": "bin/vuepress.js", @@ -9437,8 +9229,8 @@ "node": "^18.19.0 || >=20.4.0" }, "peerDependencies": { - "@vuepress/bundler-vite": "2.0.0-rc.18", - "@vuepress/bundler-webpack": "2.0.0-rc.18", + "@vuepress/bundler-vite": "2.0.0-rc.19", + "@vuepress/bundler-webpack": "2.0.0-rc.19", "vue": "^3.5.0" }, "peerDependenciesMeta": { @@ -9451,21 +9243,20 @@ } }, "node_modules/vuepress-plugin-components": { - "version": "2.0.0-rc.59", - "resolved": "https://registry.npmjs.org/vuepress-plugin-components/-/vuepress-plugin-components-2.0.0-rc.59.tgz", - "integrity": "sha512-LRA4uHW+a6D3wZkElMRmafeFhUXwwkVccWoSSnuTfI70mdqOnuaiPLQIQ0akyLBx41npervol6MRi8brqbjliw==", + "version": "2.0.0-rc.64", + "resolved": "https://registry.npmjs.org/vuepress-plugin-components/-/vuepress-plugin-components-2.0.0-rc.64.tgz", + "integrity": "sha512-rRfm6YfieQoKmfqZYlM+S5N7sU+iiwlAb80uEo+CTMm7lxsPSDRH2X13u3op35KQn/QWqkEVkf75vTesyBZZhw==", "dev": true, - "license": "MIT", "dependencies": { "@stackblitz/sdk": "^1.11.0", - "@vuepress/helper": "2.0.0-rc.56", - "@vuepress/plugin-sass-palette": "2.0.0-rc.56", - "@vueuse/core": "^11.1.0", + "@vuepress/helper": "2.0.0-rc.66", + "@vuepress/plugin-sass-palette": "2.0.0-rc.66", + "@vueuse/core": "^12.0.0", "balloon-css": "^1.2.0", "create-codepen": "^2.0.0", "qrcode": "^1.5.4", - "vue": "^3.5.12", - "vuepress-shared": "2.0.0-rc.59" + "vue": "^3.5.13", + "vuepress-shared": "2.0.0-rc.64" }, "engines": { "node": ">=18.19.0", @@ -9478,11 +9269,11 @@ "dashjs": "4.7.4", "hls.js": "^1.4.12", "mpegts.js": "^1.7.3", - "sass": "^1.80.3", - "sass-embedded": "^1.80.3", + "sass": "^1.81.0", + "sass-embedded": "^1.81.0", "sass-loader": "^16.0.2", "vidstack": "^1.12.9", - "vuepress": "2.0.0-rc.18" + "vuepress": "2.0.0-rc.19" }, "peerDependenciesMeta": { "artplayer": { @@ -9512,35 +9303,23 @@ } }, "node_modules/vuepress-plugin-md-enhance": { - "version": "2.0.0-rc.59", - "resolved": "https://registry.npmjs.org/vuepress-plugin-md-enhance/-/vuepress-plugin-md-enhance-2.0.0-rc.59.tgz", - "integrity": "sha512-XFf6OG5arp1bJHP3gUDibKcoYaWLdZvU6xXypIMXa+Q5f2I51l9zd6vuLw58DcHWQyhNUTdtDE6srohUtOxQ/A==", + "version": "2.0.0-rc.64", + "resolved": "https://registry.npmjs.org/vuepress-plugin-md-enhance/-/vuepress-plugin-md-enhance-2.0.0-rc.64.tgz", + "integrity": "sha512-pwXEDaUXyo1tfcA4n4l3Ql0aTBwju+eNO+5wL9TwtsCgCTsAo63pQIrv/XRwFuHJRHKj3HfrlEcNuDn2uxPH+A==", "dev": true, - "license": "MIT", "dependencies": { - "@mdit/plugin-alert": "^0.13.1", - "@mdit/plugin-align": "^0.13.1", - "@mdit/plugin-attrs": "^0.13.1", - "@mdit/plugin-container": "^0.13.1", - "@mdit/plugin-demo": "^0.13.1", - "@mdit/plugin-footnote": "^0.13.1", - "@mdit/plugin-include": "^0.13.1", - "@mdit/plugin-mark": "^0.13.1", - "@mdit/plugin-plantuml": "^0.13.1", - "@mdit/plugin-spoiler": "^0.13.1", - "@mdit/plugin-stylize": "^0.13.1", - "@mdit/plugin-sub": "^0.13.1", - "@mdit/plugin-sup": "^0.13.1", - "@mdit/plugin-tasklist": "^0.13.1", - "@mdit/plugin-uml": "^0.13.1", + "@mdit/plugin-container": "^0.14.0", + "@mdit/plugin-demo": "^0.14.0", + "@mdit/plugin-plantuml": "^0.14.0", + "@mdit/plugin-uml": "^0.14.0", "@types/markdown-it": "^14.1.2", - "@vuepress/helper": "2.0.0-rc.56", - "@vuepress/plugin-sass-palette": "2.0.0-rc.56", - "@vueuse/core": "^11.1.0", + "@vuepress/helper": "2.0.0-rc.66", + "@vuepress/plugin-sass-palette": "2.0.0-rc.66", + "@vueuse/core": "^12.0.0", "balloon-css": "^1.2.0", "js-yaml": "^4.1.0", - "vue": "^3.5.12", - "vuepress-shared": "2.0.0-rc.59" + "vue": "^3.5.13", + "vuepress-shared": "2.0.0-rc.64" }, "engines": { "node": ">=18.19.0", @@ -9559,10 +9338,10 @@ "markmap-view": "^0.17.0", "mermaid": "^11.2.0", "sandpack-vue3": "^3.0.0", - "sass": "^1.80.3", - "sass-embedded": "^1.80.3", + "sass": "^1.81.0", + "sass-embedded": "^1.81.0", "sass-loader": "^16.0.2", - "vuepress": "2.0.0-rc.18" + "vuepress": "2.0.0-rc.19" }, "peerDependenciesMeta": { "@vue/repl": { @@ -9610,15 +9389,13 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "license": "Python-2.0" + "dev": true }, "node_modules/vuepress-plugin-md-enhance/node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, - "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -9627,16 +9404,15 @@ } }, "node_modules/vuepress-shared": { - "version": "2.0.0-rc.59", - "resolved": "https://registry.npmjs.org/vuepress-shared/-/vuepress-shared-2.0.0-rc.59.tgz", - "integrity": "sha512-NUGEX8e4TQ2L6F7ooLDELRtUWiHxE5ztP1rJxyg9FzKZ6MiINB5b669LcQSh/xAlY4fm9p80Y4C/52+zmNDEoA==", + "version": "2.0.0-rc.64", + "resolved": "https://registry.npmjs.org/vuepress-shared/-/vuepress-shared-2.0.0-rc.64.tgz", + "integrity": "sha512-YA0z7Pwob8Bj7uHNHBXGpH6GeaLAhBFlvBtTM136zZhsUb2mQptB67y1B03RLDYtfzMP06WKCh449azdVbZykA==", "dev": true, - "license": "MIT", "dependencies": { - "@vuepress/helper": "2.0.0-rc.56", - "@vueuse/core": "^11.1.0", + "@vuepress/helper": "2.0.0-rc.66", + "@vueuse/core": "^12.0.0", "dayjs": "^1.11.13", - "vue": "^3.5.12" + "vue": "^3.5.13" }, "engines": { "node": ">=18.19.0", @@ -9645,50 +9421,52 @@ "yarn": ">=2" }, "peerDependencies": { - "vuepress": "2.0.0-rc.18" + "vuepress": "2.0.0-rc.19" } }, "node_modules/vuepress-theme-hope": { - "version": "2.0.0-rc.59", - "resolved": "https://registry.npmjs.org/vuepress-theme-hope/-/vuepress-theme-hope-2.0.0-rc.59.tgz", - "integrity": "sha512-o+5P+xMy0y2HPWb3bmVE2AMWbMCdsdDfET6APWqXm6ccyhXW7cDStwho5cuwQmVasqSZSYS950dAahEcsj0wlg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vuepress/helper": "2.0.0-rc.56", - "@vuepress/plugin-active-header-links": "2.0.0-rc.55", - "@vuepress/plugin-back-to-top": "2.0.0-rc.56", - "@vuepress/plugin-blog": "2.0.0-rc.56", - "@vuepress/plugin-catalog": "2.0.0-rc.56", - "@vuepress/plugin-comment": "2.0.0-rc.56", - "@vuepress/plugin-copy-code": "2.0.0-rc.56", - "@vuepress/plugin-copyright": "2.0.0-rc.56", - "@vuepress/plugin-git": "2.0.0-rc.54", - "@vuepress/plugin-links-check": "2.0.0-rc.56", - "@vuepress/plugin-markdown-hint": "2.0.0-rc.56", - "@vuepress/plugin-markdown-image": "2.0.0-rc.56", - "@vuepress/plugin-markdown-math": "2.0.0-rc.56", - "@vuepress/plugin-markdown-tab": "2.0.0-rc.56", - "@vuepress/plugin-notice": "2.0.0-rc.56", - "@vuepress/plugin-nprogress": "2.0.0-rc.56", - "@vuepress/plugin-photo-swipe": "2.0.0-rc.56", - "@vuepress/plugin-reading-time": "2.0.0-rc.56", - "@vuepress/plugin-redirect": "2.0.0-rc.56", - "@vuepress/plugin-rtl": "2.0.0-rc.56", - "@vuepress/plugin-sass-palette": "2.0.0-rc.56", - "@vuepress/plugin-seo": "2.0.0-rc.56", - "@vuepress/plugin-shiki": "2.0.0-rc.56", - "@vuepress/plugin-sitemap": "2.0.0-rc.56", - "@vuepress/plugin-theme-data": "2.0.0-rc.56", - "@vuepress/plugin-watermark": "2.0.0-rc.56", - "@vueuse/core": "^11.1.0", + "version": "2.0.0-rc.64", + "resolved": "https://registry.npmjs.org/vuepress-theme-hope/-/vuepress-theme-hope-2.0.0-rc.64.tgz", + "integrity": "sha512-nRy00CHINQXeKa7ztOyRyYPnP0rzL2iyEDTXMGOEbBtYS2RCp6CM/587nCKV7VXrFPY/3Ps/4C2Abf9kTkMdwA==", + "dev": true, + "dependencies": { + "@vuepress/helper": "2.0.0-rc.66", + "@vuepress/plugin-active-header-links": "2.0.0-rc.66", + "@vuepress/plugin-back-to-top": "2.0.0-rc.66", + "@vuepress/plugin-blog": "2.0.0-rc.66", + "@vuepress/plugin-catalog": "2.0.0-rc.66", + "@vuepress/plugin-comment": "2.0.0-rc.66", + "@vuepress/plugin-copy-code": "2.0.0-rc.66", + "@vuepress/plugin-copyright": "2.0.0-rc.66", + "@vuepress/plugin-git": "2.0.0-rc.66", + "@vuepress/plugin-links-check": "2.0.0-rc.66", + "@vuepress/plugin-markdown-ext": "2.0.0-rc.66", + "@vuepress/plugin-markdown-hint": "2.0.0-rc.66", + "@vuepress/plugin-markdown-image": "2.0.0-rc.66", + "@vuepress/plugin-markdown-include": "2.0.0-rc.66", + "@vuepress/plugin-markdown-math": "2.0.0-rc.66", + "@vuepress/plugin-markdown-stylize": "2.0.0-rc.66", + "@vuepress/plugin-markdown-tab": "2.0.0-rc.66", + "@vuepress/plugin-notice": "2.0.0-rc.66", + "@vuepress/plugin-nprogress": "2.0.0-rc.66", + "@vuepress/plugin-photo-swipe": "2.0.0-rc.66", + "@vuepress/plugin-reading-time": "2.0.0-rc.66", + "@vuepress/plugin-redirect": "2.0.0-rc.66", + "@vuepress/plugin-rtl": "2.0.0-rc.66", + "@vuepress/plugin-sass-palette": "2.0.0-rc.66", + "@vuepress/plugin-seo": "2.0.0-rc.66", + "@vuepress/plugin-shiki": "2.0.0-rc.66", + "@vuepress/plugin-sitemap": "2.0.0-rc.66", + "@vuepress/plugin-theme-data": "2.0.0-rc.66", + "@vuepress/plugin-watermark": "2.0.0-rc.66", + "@vueuse/core": "^12.0.0", "balloon-css": "^1.2.0", - "bcrypt-ts": "^5.0.2", + "bcrypt-ts": "^5.0.3", "chokidar": "^3.6.0", - "vue": "^3.5.12", - "vuepress-plugin-components": "2.0.0-rc.59", - "vuepress-plugin-md-enhance": "2.0.0-rc.59", - "vuepress-shared": "2.0.0-rc.59" + "vue": "^3.5.13", + "vuepress-plugin-components": "2.0.0-rc.64", + "vuepress-plugin-md-enhance": "2.0.0-rc.64", + "vuepress-shared": "2.0.0-rc.64" }, "engines": { "node": ">=18.19.0", @@ -9697,18 +9475,18 @@ "yarn": ">=2" }, "peerDependencies": { - "@vuepress/plugin-docsearch": "2.0.0-rc.56", - "@vuepress/plugin-feed": "2.0.0-rc.56", - "@vuepress/plugin-prismjs": "2.0.0-rc.56", - "@vuepress/plugin-pwa": "2.0.0-rc.56", - "@vuepress/plugin-revealjs": "2.0.0-rc.56", - "@vuepress/plugin-search": "2.0.0-rc.55", + "@vuepress/plugin-docsearch": "2.0.0-rc.66", + "@vuepress/plugin-feed": "2.0.0-rc.66", + "@vuepress/plugin-prismjs": "2.0.0-rc.66", + "@vuepress/plugin-pwa": "2.0.0-rc.66", + "@vuepress/plugin-revealjs": "2.0.0-rc.66", + "@vuepress/plugin-search": "2.0.0-rc.66", + "@vuepress/plugin-slimsearch": "2.0.0-rc.66", "nodejs-jieba": "^0.2.1", - "sass": "^1.80.3", - "sass-embedded": "^1.80.3", + "sass": "^1.81.0", + "sass-embedded": "^1.81.0", "sass-loader": "^16.0.2", - "vuepress": "2.0.0-rc.18", - "vuepress-plugin-search-pro": "2.0.0-rc.59" + "vuepress": "2.0.0-rc.19" }, "peerDependenciesMeta": { "@vuepress/plugin-docsearch": { @@ -9729,6 +9507,9 @@ "@vuepress/plugin-search": { "optional": true }, + "@vuepress/plugin-slimsearch": { + "optional": true + }, "nodejs-jieba": { "optional": true }, @@ -9740,45 +9521,9 @@ }, "sass-loader": { "optional": true - }, - "vuepress-plugin-search-pro": { - "optional": true } } }, - "node_modules/vuepress-theme-hope/node_modules/@vuepress/plugin-markdown-image": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-markdown-image/-/plugin-markdown-image-2.0.0-rc.56.tgz", - "integrity": "sha512-oIqVz1rvUfteIQhESZNuTgeLU9neLVrdC041e+yRakJShAGKXVPJoZE09wjQoHZM0RE2Qkd+EkAYQGB7fKFgbw==", - "dev": true, - "dependencies": { - "@mdit/plugin-figure": "^0.13.1", - "@mdit/plugin-img-lazyload": "^0.13.1", - "@mdit/plugin-img-mark": "^0.13.1", - "@mdit/plugin-img-size": "^0.13.1", - "@types/markdown-it": "^14.1.2", - "@vuepress/helper": "2.0.0-rc.56" - }, - "peerDependencies": { - "vuepress": "2.0.0-rc.18" - } - }, - "node_modules/vuepress-theme-hope/node_modules/@vuepress/plugin-markdown-tab": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-markdown-tab/-/plugin-markdown-tab-2.0.0-rc.56.tgz", - "integrity": "sha512-qqL+mlGuccnyJg7rdOBXJg5UEppMxObQZfhnuoiuu4BE8C0kV7G/myMOWsHLH0My8zpXdl5beKJqOdrjZapJqg==", - "dev": true, - "dependencies": { - "@mdit/plugin-tab": "^0.13.2", - "@types/markdown-it": "^14.1.2", - "@vuepress/helper": "2.0.0-rc.56", - "@vueuse/core": "^11.1.0", - "vue": "^3.5.12" - }, - "peerDependencies": { - "vuepress": "2.0.0-rc.18" - } - }, "node_modules/wait-on": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-8.0.1.tgz", @@ -9803,7 +9548,6 @@ "resolved": "https://registry.npmjs.org/watermark-js-plus/-/watermark-js-plus-1.5.7.tgz", "integrity": "sha512-KaQEUnvBX5em2hBeuKcpAASpV+sO1j8NbXY7FL7jb0w1TCKmMSyn8nkj2e+KeleuQ1iwyXHEMFdSWXDIQsACYQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=20.0.0" } @@ -9850,8 +9594,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", - "dev": true, - "license": "ISC" + "dev": true }, "node_modules/wrap-ansi": { "version": "7.0.0", @@ -9880,15 +9623,13 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true, - "license": "ISC" + "dev": true }, "node_modules/yargs": { "version": "15.4.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", "dev": true, - "license": "MIT", "dependencies": { "cliui": "^6.0.0", "decamelize": "^1.2.0", @@ -9911,7 +9652,6 @@ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", "dev": true, - "license": "ISC", "dependencies": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" @@ -9935,7 +9675,6 @@ "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.1.tgz", "integrity": "sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=18" }, @@ -9948,7 +9687,6 @@ "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", "dev": true, - "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -10228,6 +9966,13 @@ "dev": true, "optional": true }, + "@esbuild/openbsd-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.0.tgz", + "integrity": "sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg==", + "dev": true, + "optional": true + }, "@esbuild/openbsd-x64": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", @@ -10299,65 +10044,12 @@ "mlly": "^1.7.1" } }, - "@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "optional": true, - "peer": true - }, - "@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, - "optional": true, - "peer": true - }, - "@jridgewell/source-map": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", - "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25" - } - }, "@jridgewell/sourcemap-codec": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", "dev": true }, - "@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, "@lit-labs/ssr-dom-shim": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.2.1.tgz", @@ -10469,216 +10161,177 @@ } }, "@mdit/plugin-alert": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-alert/-/plugin-alert-0.13.1.tgz", - "integrity": "sha512-3LMYQQ3QP6TUx6zmtmuoHJScST5SVoPZlNuuF4S6PUZvJIwtlITF+eFNjDrA7UQx0PUdCgVHmwu5kYliq+BNtg==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@mdit/plugin-alert/-/plugin-alert-0.14.0.tgz", + "integrity": "sha512-a9/E6AZkCdepiseaS7VzjTPzlDVEpDXbgfspT1V0LVJ0xHiOlPNaUhB4vuRavETFyFmbmx8Lq8SvjvN6VdIz7Q==", "dev": true, "requires": { "@types/markdown-it": "^14.1.2" } }, "@mdit/plugin-align": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-align/-/plugin-align-0.13.1.tgz", - "integrity": "sha512-g8je53oEpYNHEudhtB5ViSiAaiMcca+hvoGbInhLl979tWuvEosOs0oWH2X3GM4f6goTGx8gLwzA10Z5C4FxIQ==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@mdit/plugin-align/-/plugin-align-0.14.0.tgz", + "integrity": "sha512-lm7epUka2zMHh6DpU1juX7eBAZHaGk+gcMNPknLb9LnP+zgKqEQ6Dl/86z24N9h9biAnp4AoY1uFMQB5mMvPHw==", "dev": true, "requires": { - "@mdit/plugin-container": "0.13.1", + "@mdit/plugin-container": "0.14.0", "@types/markdown-it": "^14.1.2" } }, "@mdit/plugin-attrs": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-attrs/-/plugin-attrs-0.13.1.tgz", - "integrity": "sha512-3saBw5W2y3T0QNbui+uk7nfD36FOoBWNQImk+pbMGpKRqunjouiYP4ZtnttT/AiieGbZBVaOqhM4e01Uyua8VA==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@mdit/plugin-attrs/-/plugin-attrs-0.14.0.tgz", + "integrity": "sha512-/SK/mDXF+Zly7HN3ps8RB83CIWKv8r9FPGxmq9DknpXhFFOMlE5UIP9l7E0ysWmlKElfoEq9hYgUY9Ieerphtg==", "dev": true, "requires": { + "@mdit/helper": "0.14.0", "@types/markdown-it": "^14.1.2" } }, "@mdit/plugin-container": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-container/-/plugin-container-0.13.1.tgz", - "integrity": "sha512-mFfm7YViyLHo8uORVa9oLi9+acZZoSVdPf3WPqzC/yLZAJbF27rfJgWZ9Kylt+tyaAYng8L4DiSeVcSNUIHF1A==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@mdit/plugin-container/-/plugin-container-0.14.0.tgz", + "integrity": "sha512-sYjR9GPPkdItjGXw2m4f2iKAvKK+9egq/3wnzNnsouK1Hz0Qz8rQM1VELQLBK16PJwqStGNfTQC31BeM7gVmIg==", "dev": true, "requires": { "@types/markdown-it": "^14.1.2" } }, "@mdit/plugin-demo": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-demo/-/plugin-demo-0.13.1.tgz", - "integrity": "sha512-ne36FB7jstUblatow7ed1Z3Nm0zootM7A6b+77xEw7aJnXHkM5tJLbBfS6l8WN1Ze7fWVZbP7xQkI3wRvjqrqg==", - "dev": true, - "requires": { - "@types/markdown-it": "^14.1.2" - } - }, - "@mdit/plugin-figure": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-figure/-/plugin-figure-0.13.1.tgz", - "integrity": "sha512-bxeUVMPAuXHYRqPzU+1ux7R3LkpyHTdavCa05rQUhzDI07N+BZDE7oOABXnnFbx6ESamzu3/FBtq9VKjoifLmw==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@mdit/plugin-demo/-/plugin-demo-0.14.0.tgz", + "integrity": "sha512-pp5XTESSmvUKpIJMyM1RFCddXjTXhgw8HKDPAMmIc2BpeBzFUBgNBA3JBULE8KiZVPJBdc2HuswQFOYwb6IQ/A==", "dev": true, "requires": { "@types/markdown-it": "^14.1.2" } }, "@mdit/plugin-footnote": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-footnote/-/plugin-footnote-0.13.1.tgz", - "integrity": "sha512-46TzNvY9QXO5y6MbXlewCe+gfw3lgF2IFQCs0enaWVSgKNaGxOuecDR68SlbLPc7unJQCcs5Bb/XB4xsx0depQ==", - "dev": true, - "requires": { - "@types/markdown-it": "^14.1.2" - } - }, - "@mdit/plugin-img-lazyload": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-img-lazyload/-/plugin-img-lazyload-0.13.1.tgz", - "integrity": "sha512-DPzR+yabbgqHWHb8oetOj56TtZzOcn5YZjSTssoh7lY5hp/Yy7jWvlLDrSw/LiXkYEhyocUee78enhTodBEpHQ==", - "dev": true, - "requires": { - "@types/markdown-it": "^14.1.2" - } - }, - "@mdit/plugin-img-mark": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-img-mark/-/plugin-img-mark-0.13.1.tgz", - "integrity": "sha512-HOALB1nILV5vkopSKPrclkwwc5WGbpuAWxuOLTz/teOifE8E4JsbiFivcM6URMP1lZXzRBXoniQCCOUhWRis8A==", - "dev": true, - "requires": { - "@types/markdown-it": "^14.1.2" - } - }, - "@mdit/plugin-img-size": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-img-size/-/plugin-img-size-0.13.1.tgz", - "integrity": "sha512-cgihl72BNzij7GXjrqcKhl2eOqAlqWHiImOgblJPghDFNFKnnynty/Bf9nwbj8hTnhVWznFeuwawzXBfKYNbkg==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@mdit/plugin-footnote/-/plugin-footnote-0.14.0.tgz", + "integrity": "sha512-GaBn/j7TiC3tFwR0iRKyo133FvJtPQ1qo0K3NGKULWD8M4i1K2tEuA6qRKELh3DlsNKxK6G81KnQTl/87gR3rw==", "dev": true, "requires": { "@types/markdown-it": "^14.1.2" } }, "@mdit/plugin-include": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-include/-/plugin-include-0.13.1.tgz", - "integrity": "sha512-rWGJ3/L2Ocv+8KDNoXPb6H1f+aLqx0FzJKcNqJl+0HOAEScuyKS1GC4OxeWefVMQ87QoG/mYqoCbpDsJeiDbLQ==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@mdit/plugin-include/-/plugin-include-0.14.0.tgz", + "integrity": "sha512-Y4XXGz9lhdSEctqMdmrN4R4nJPfgPSrtTwyptiN5ArT8fx+UIJId8AYBk5ybMZBAYne2QBHI/8+2O0xrUxJzYw==", "dev": true, "requires": { + "@mdit/helper": "0.14.0", "@types/markdown-it": "^14.1.2", "upath": "^2.0.1" } }, "@mdit/plugin-katex-slim": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-katex-slim/-/plugin-katex-slim-0.13.1.tgz", - "integrity": "sha512-OO4n51aLo0Igv0aICXOaTO5+ZW/jW8Lnl8u1kxs2zkFVNUqpqNHAo8l4QxtscQk5L4XhXGgaTj2ZgAv7rtH96Q==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@mdit/plugin-katex-slim/-/plugin-katex-slim-0.14.0.tgz", + "integrity": "sha512-GztODGcbbd+Glmwrin8yeR6KDESyFwxKkwe1u40XQ4vAImtOswQbAk5suoFGySiuONzGiu/4RLOKnYv5Unq3jQ==", "dev": true, "requires": { - "@mdit/plugin-tex": "0.13.1", + "@mdit/helper": "0.14.0", + "@mdit/plugin-tex": "0.14.0", "@types/katex": "^0.16.7", "@types/markdown-it": "^14.1.2" } }, "@mdit/plugin-mark": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-mark/-/plugin-mark-0.13.1.tgz", - "integrity": "sha512-UV+7cSY8iQXlfnrIJ/gEpgwiL2SSVzVLtaWMOV0J4tRSsdtN8ZXnJn/gC547SxBaOLIkt+0ObSskXaCH/UzuIA==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@mdit/plugin-mark/-/plugin-mark-0.14.0.tgz", + "integrity": "sha512-NKJB92pJissct4HCDv+GK8dMF/viX5fzf6zrO9zBmgFRfdeo6CqjuVWh+Se/mPtqwhk1f2EX80YlOXorWNjXKQ==", "dev": true, "requires": { "@types/markdown-it": "^14.1.2" } }, "@mdit/plugin-mathjax-slim": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-mathjax-slim/-/plugin-mathjax-slim-0.13.1.tgz", - "integrity": "sha512-ZFtKG2BtLAk1BarJZei9HP4aK0vNU7YvDb+R+nApK7MRmLQ53xHe7upu3qlfNBoOZWHXsdRmcz0G4xL3oxzlqA==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@mdit/plugin-mathjax-slim/-/plugin-mathjax-slim-0.14.0.tgz", + "integrity": "sha512-AOFHQ5wN8IDV8d96MH3w9irHNguLtWbhYajQcc+O5wGeWxDsd5KMAd4StgERETxo6XgLxr0NRC8HzxSMPrC2aw==", "dev": true, "requires": { - "@mdit/plugin-tex": "0.13.1", + "@mdit/plugin-tex": "0.14.0", "@types/markdown-it": "^14.1.2", "upath": "^2.0.1" } }, "@mdit/plugin-plantuml": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-plantuml/-/plugin-plantuml-0.13.1.tgz", - "integrity": "sha512-qupMO/lG1mDYaGHSutB9AO1TsxHjmp4yFnvp3VBNNRdVh9lqWhXFv/htrnr0IGEWAmlik6zlkCvz/YrKRONV5A==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@mdit/plugin-plantuml/-/plugin-plantuml-0.14.0.tgz", + "integrity": "sha512-AZy/o6Uvjd46GWoisYLQBL37ET0T+XscI+E8nUuZGu/ihAhoZU3jxeE97WFPwBa5T3hrNd9L1XfLXTTDM2ZQWw==", "dev": true, "requires": { - "@mdit/plugin-uml": "0.13.1", + "@mdit/plugin-uml": "0.14.0", "@types/markdown-it": "^14.1.2" } }, "@mdit/plugin-spoiler": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-spoiler/-/plugin-spoiler-0.13.1.tgz", - "integrity": "sha512-6aOD+kjGavkn+Ta0Iq8AUfBG3UsKsL5e0pxi0Eng13lIEp8DrDw36W+E6fLOFtX8Te3ays6eTkTc1I5WzHO0Gw==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@mdit/plugin-spoiler/-/plugin-spoiler-0.14.0.tgz", + "integrity": "sha512-c+tSj35JygQF9gNRAcH3gk68pBpjS7zGiooz/UK+tw8GSqez2c1Z+PWvu1u4xX0O/HO3y+amu7GqTjwkfgLC7g==", "dev": true, "requires": { "@types/markdown-it": "^14.1.2" } }, "@mdit/plugin-stylize": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-stylize/-/plugin-stylize-0.13.1.tgz", - "integrity": "sha512-1v+3H1nMMvXsbu6iyV1pQ7WccrRNkuHovkIAp04Vj0FtbjnKrBHlmzFZace5OaD2RcZ0fn6qRpyR+/AIMjUvtQ==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@mdit/plugin-stylize/-/plugin-stylize-0.14.0.tgz", + "integrity": "sha512-oJFR+6JqWNnEjFsSO8FsMS92MNVzEaI+Re/3MX6OerJ7/ytdU8EkdgU8hcNcAGeT437SIKZsH9pRnxBupx0J7w==", "dev": true, "requires": { "@types/markdown-it": "^14.1.2" } }, "@mdit/plugin-sub": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-sub/-/plugin-sub-0.13.1.tgz", - "integrity": "sha512-2rIvEl6pXUoXIm3JMO5ZOQ+vWIeFXmLkqxcmTZB2yOIfhYdLwIcSyquRwtI2AX8zCuvaTdiQ/aypvIE4tDoURw==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@mdit/plugin-sub/-/plugin-sub-0.14.0.tgz", + "integrity": "sha512-wva0pmw67t1aNZR7I+1GUyaWigJp+cGcPFvuwYviUuZh9npZXBIAdq1cCvycPaM29OT+LoBj5jdeydA81DKYSg==", "dev": true, "requires": { + "@mdit/helper": "0.14.0", "@types/markdown-it": "^14.1.2" } }, "@mdit/plugin-sup": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-sup/-/plugin-sup-0.13.1.tgz", - "integrity": "sha512-vkNif2Rbj7/gtk4/HJt5hnb+Dcbnek/V4HtLdtqUUnq9bIbzFBpYw5jZ1ZKKZeetDtRvOUPH5oy5d7iXAHorUg==", - "dev": true, - "requires": { - "@types/markdown-it": "^14.1.2" - } - }, - "@mdit/plugin-tab": { - "version": "0.13.2", - "resolved": "https://registry.npmjs.org/@mdit/plugin-tab/-/plugin-tab-0.13.2.tgz", - "integrity": "sha512-evpIXvo6vXRWhgNE6vu4ok1I2dVOzrBYmBUGc1gW8nT9MvkW9litu7RbJ6CafscqaiiYRIM5Oib1ahS0lwte6g==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@mdit/plugin-sup/-/plugin-sup-0.14.0.tgz", + "integrity": "sha512-QUwuCXQHS2atYv4SFfslVsuQLI1epDBie4Sw+E7XDwnbl9/o/vcJGkqdO4HKq8d73efowlWp2tGcpCxH+AeTWA==", "dev": true, "requires": { + "@mdit/helper": "0.14.0", "@types/markdown-it": "^14.1.2" } }, "@mdit/plugin-tasklist": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-tasklist/-/plugin-tasklist-0.13.1.tgz", - "integrity": "sha512-flEWnDJFEB7QZIHRwtkVjAEZe9ONiRQLRg7oazRDBM/3Z0rf28blxOx7qj2QZ/FVzQnRRZTgjFQkpiz61IckKQ==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@mdit/plugin-tasklist/-/plugin-tasklist-0.14.0.tgz", + "integrity": "sha512-qKXt3td+A4pWbAYChPgOO+Ne9dOkb3SfrbyWE15M0AsIfVDizcq4wwVp8OQ25VAU5e4VisKiZ1XOE6xRoZHCbg==", "dev": true, "requires": { "@types/markdown-it": "^14.1.2" } }, "@mdit/plugin-tex": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-tex/-/plugin-tex-0.13.1.tgz", - "integrity": "sha512-lkRf6XrfVfS11FzT3hiooWdOUPJfAd/cnAv4NN/4WU7qOEz0e0HBVQO8PQb5CPwrE94Ld4+E6rQwJfVH1grkwQ==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@mdit/plugin-tex/-/plugin-tex-0.14.0.tgz", + "integrity": "sha512-fDigmoJLm3TzcS2nHrgc70EC680QTD9v+PlUDJX8gslE489+o0jRKB6/l6YuzBdpXNRcbrDNeo8q+oODlo/Y2w==", "dev": true, "requires": { "@types/markdown-it": "^14.1.2" } }, "@mdit/plugin-uml": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/@mdit/plugin-uml/-/plugin-uml-0.13.1.tgz", - "integrity": "sha512-JdCOg25OyG+QJFAba6AWwdpkaOjuht5VmOqYt4/h/AzLsIHh/2j+TnCZBn0XQm3D8yJ9Y4w4oouS4wpPduRW0A==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@mdit/plugin-uml/-/plugin-uml-0.14.0.tgz", + "integrity": "sha512-eIR4CiJfATlVAGuJh5Nd9L23zaN/ZDXc13SI/CaEPD+JG9/0h9XtyuceD5ncZDuEhmLnlxJua50Qek8NaObWDQ==", "dev": true, "requires": { + "@mdit/helper": "0.14.0", "@types/markdown-it": "^14.1.2" } }, @@ -10840,114 +10493,135 @@ "peer": true }, "@rollup/rollup-android-arm-eabi": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz", - "integrity": "sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.28.1.tgz", + "integrity": "sha512-2aZp8AES04KI2dy3Ss6/MDjXbwBzj+i0GqKtWXgw2/Ma6E4jJvujryO6gJAghIRVz7Vwr9Gtl/8na3nDUKpraQ==", "dev": true, "optional": true }, "@rollup/rollup-android-arm64": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.0.tgz", - "integrity": "sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.28.1.tgz", + "integrity": "sha512-EbkK285O+1YMrg57xVA+Dp0tDBRB93/BZKph9XhMjezf6F4TpYjaUSuPt5J0fZXlSag0LmZAsTmdGGqPp4pQFA==", "dev": true, "optional": true }, "@rollup/rollup-darwin-arm64": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.0.tgz", - "integrity": "sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.28.1.tgz", + "integrity": "sha512-prduvrMKU6NzMq6nxzQw445zXgaDBbMQvmKSJaxpaZ5R1QDM8w+eGxo6Y/jhT/cLoCvnZI42oEqf9KQNYz1fqQ==", "dev": true, "optional": true }, "@rollup/rollup-darwin-x64": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.0.tgz", - "integrity": "sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.28.1.tgz", + "integrity": "sha512-WsvbOunsUk0wccO/TV4o7IKgloJ942hVFK1CLatwv6TJspcCZb9umQkPdvB7FihmdxgaKR5JyxDjWpCOp4uZlQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-freebsd-arm64": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.28.1.tgz", + "integrity": "sha512-HTDPdY1caUcU4qK23FeeGxCdJF64cKkqajU0iBnTVxS8F7H/7BewvYoG+va1KPSL63kQ1PGNyiwKOfReavzvNA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-freebsd-x64": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.28.1.tgz", + "integrity": "sha512-m/uYasxkUevcFTeRSM9TeLyPe2QDuqtjkeoTpP9SW0XxUWfcYrGDMkO/m2tTw+4NMAF9P2fU3Mw4ahNvo7QmsQ==", "dev": true, "optional": true }, "@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.0.tgz", - "integrity": "sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.28.1.tgz", + "integrity": "sha512-QAg11ZIt6mcmzpNE6JZBpKfJaKkqTm1A9+y9O+frdZJEuhQxiugM05gnCWiANHj4RmbgeVJpTdmKRmH/a+0QbA==", "dev": true, "optional": true }, "@rollup/rollup-linux-arm-musleabihf": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.0.tgz", - "integrity": "sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.28.1.tgz", + "integrity": "sha512-dRP9PEBfolq1dmMcFqbEPSd9VlRuVWEGSmbxVEfiq2cs2jlZAl0YNxFzAQS2OrQmsLBLAATDMb3Z6MFv5vOcXg==", "dev": true, "optional": true }, "@rollup/rollup-linux-arm64-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.0.tgz", - "integrity": "sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.28.1.tgz", + "integrity": "sha512-uGr8khxO+CKT4XU8ZUH1TTEUtlktK6Kgtv0+6bIFSeiSlnGJHG1tSFSjm41uQ9sAO/5ULx9mWOz70jYLyv1QkA==", "dev": true, "optional": true }, "@rollup/rollup-linux-arm64-musl": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.0.tgz", - "integrity": "sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.28.1.tgz", + "integrity": "sha512-QF54q8MYGAqMLrX2t7tNpi01nvq5RI59UBNx+3+37zoKX5KViPo/gk2QLhsuqok05sSCRluj0D00LzCwBikb0A==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.28.1.tgz", + "integrity": "sha512-vPul4uodvWvLhRco2w0GcyZcdyBfpfDRgNKU+p35AWEbJ/HPs1tOUrkSueVbBS0RQHAf/A+nNtDpvw95PeVKOA==", "dev": true, "optional": true }, "@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.0.tgz", - "integrity": "sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.28.1.tgz", + "integrity": "sha512-pTnTdBuC2+pt1Rmm2SV7JWRqzhYpEILML4PKODqLz+C7Ou2apEV52h19CR7es+u04KlqplggmN9sqZlekg3R1A==", "dev": true, "optional": true }, "@rollup/rollup-linux-riscv64-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.0.tgz", - "integrity": "sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.28.1.tgz", + "integrity": "sha512-vWXy1Nfg7TPBSuAncfInmAI/WZDd5vOklyLJDdIRKABcZWojNDY0NJwruY2AcnCLnRJKSaBgf/GiJfauu8cQZA==", "dev": true, "optional": true }, "@rollup/rollup-linux-s390x-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.0.tgz", - "integrity": "sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.28.1.tgz", + "integrity": "sha512-/yqC2Y53oZjb0yz8PVuGOQQNOTwxcizudunl/tFs1aLvObTclTwZ0JhXF2XcPT/zuaymemCDSuuUPXJJyqeDOg==", "dev": true, "optional": true }, "@rollup/rollup-linux-x64-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.0.tgz", - "integrity": "sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.28.1.tgz", + "integrity": "sha512-fzgeABz7rrAlKYB0y2kSEiURrI0691CSL0+KXwKwhxvj92VULEDQLpBYLHpF49MSiPG4sq5CK3qHMnb9tlCjBw==", "dev": true, "optional": true }, "@rollup/rollup-linux-x64-musl": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.0.tgz", - "integrity": "sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.28.1.tgz", + "integrity": "sha512-xQTDVzSGiMlSshpJCtudbWyRfLaNiVPXt1WgdWTwWz9n0U12cI2ZVtWe/Jgwyv/6wjL7b66uu61Vg0POWVfz4g==", "dev": true, "optional": true }, "@rollup/rollup-win32-arm64-msvc": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.0.tgz", - "integrity": "sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.28.1.tgz", + "integrity": "sha512-wSXmDRVupJstFP7elGMgv+2HqXelQhuNf+IS4V+nUpNVi/GUiBgDmfwD0UGN3pcAnWsgKG3I52wMOBnk1VHr/A==", "dev": true, "optional": true }, "@rollup/rollup-win32-ia32-msvc": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.0.tgz", - "integrity": "sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.28.1.tgz", + "integrity": "sha512-ZkyTJ/9vkgrE/Rk9vhMXhf8l9D+eAhbAVbsGsXKy2ohmJaWg0LPQLnIxRdRp/bKyr8tXuPlXhIoGlEB5XpJnGA==", "dev": true, "optional": true }, "@rollup/rollup-win32-x64-msvc": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.0.tgz", - "integrity": "sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.28.1.tgz", + "integrity": "sha512-ZvK2jBafvttJjoIdKm/Q/Bh7IJ1Ose9IBOwpOXcOvW3ikGTQGmKDgxTC6oCAzW6PynbkKP8+um1du81XJHZ0JA==", "dev": true, "optional": true }, @@ -10958,53 +10632,53 @@ "dev": true }, "@shikijs/core": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.22.0.tgz", - "integrity": "sha512-S8sMe4q71TJAW+qG93s5VaiihujRK6rqDFqBnxqvga/3LvqHEnxqBIOPkt//IdXVtHkQWKu4nOQNk0uBGicU7Q==", + "version": "1.24.2", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.24.2.tgz", + "integrity": "sha512-BpbNUSKIwbKrRRA+BQj0BEWSw+8kOPKDJevWeSE/xIqGX7K0xrCZQ9kK0nnEQyrzsUoka1l81ZtJ2mGaCA32HQ==", "dev": true, "requires": { - "@shikijs/engine-javascript": "1.22.0", - "@shikijs/engine-oniguruma": "1.22.0", - "@shikijs/types": "1.22.0", + "@shikijs/engine-javascript": "1.24.2", + "@shikijs/engine-oniguruma": "1.24.2", + "@shikijs/types": "1.24.2", "@shikijs/vscode-textmate": "^9.3.0", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.3" } }, "@shikijs/engine-javascript": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-1.22.0.tgz", - "integrity": "sha512-AeEtF4Gcck2dwBqCFUKYfsCq0s+eEbCEbkUuFou53NZ0sTGnJnJ/05KHQFZxpii5HMXbocV9URYVowOP2wH5kw==", + "version": "1.24.2", + "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-1.24.2.tgz", + "integrity": "sha512-EqsmYBJdLEwEiO4H+oExz34a5GhhnVp+jH9Q/XjPjmBPc6TE/x4/gD0X3i0EbkKKNqXYHHJTJUpOLRQNkEzS9Q==", "dev": true, "requires": { - "@shikijs/types": "1.22.0", + "@shikijs/types": "1.24.2", "@shikijs/vscode-textmate": "^9.3.0", - "oniguruma-to-js": "0.4.3" + "oniguruma-to-es": "0.7.0" } }, "@shikijs/engine-oniguruma": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-1.22.0.tgz", - "integrity": "sha512-5iBVjhu/DYs1HB0BKsRRFipRrD7rqjxlWTj4F2Pf+nQSPqc3kcyqFFeZXnBMzDf0HdqaFVvhDRAGiYNvyLP+Mw==", + "version": "1.24.2", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-1.24.2.tgz", + "integrity": "sha512-ZN6k//aDNWRJs1uKB12pturKHh7GejKugowOFGAuG7TxDRLod1Bd5JhpOikOiFqPmKjKEPtEA6mRCf7q3ulDyQ==", "dev": true, "requires": { - "@shikijs/types": "1.22.0", + "@shikijs/types": "1.24.2", "@shikijs/vscode-textmate": "^9.3.0" } }, "@shikijs/transformers": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/@shikijs/transformers/-/transformers-1.22.0.tgz", - "integrity": "sha512-k7iMOYuGQA62KwAuJOQBgH2IQb5vP8uiB3lMvAMGUgAMMurePOx3Z7oNqJdcpxqZP6I9cc7nc4DNqSKduCxmdg==", + "version": "1.24.2", + "resolved": "https://registry.npmjs.org/@shikijs/transformers/-/transformers-1.24.2.tgz", + "integrity": "sha512-cIwn8YSwO3bsWKJ+pezcXY1Vq0BVwvuLes1TZSC5+Awi6Tsfqhf3vBahOIqZK1rraMKOti2VEAEF/95oXMig1w==", "dev": true, "requires": { - "shiki": "1.22.0" + "shiki": "1.24.2" } }, "@shikijs/types": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-1.22.0.tgz", - "integrity": "sha512-Fw/Nr7FGFhlQqHfxzZY8Cwtwk5E9nKDUgeLjZgt3UuhcM3yJR9xj3ZGNravZZok8XmEZMiYkSMTPlPkULB8nww==", + "version": "1.24.2", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-1.24.2.tgz", + "integrity": "sha512-bdeWZiDtajGLG9BudI0AHet0b6e7FbR0EsE4jpGaI0YwHm/XJunI9+3uZnzFtX65gsyJ6ngCIWUfA4NWRPnBkQ==", "dev": true, "requires": { "@shikijs/vscode-textmate": "^9.3.0", @@ -11012,9 +10686,9 @@ } }, "@shikijs/vscode-textmate": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-9.3.0.tgz", - "integrity": "sha512-jn7/7ky30idSkd/O5yDBfAnVt+JJpepofP/POZ1iMOxK59cOfqIgg/Dj0eFsjOTMw+4ycJN0uhZH/Eb0bs/EUA==", + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-9.3.1.tgz", + "integrity": "sha512-79QfK1393x9Ho60QFyLti+QfdJzRQCVLFb97kOIV7Eo9vQU/roINgk7m24uv0a7AUvN//RDH36FLjjK48v0s9g==", "dev": true }, "@sideway/address": { @@ -11475,15 +11149,15 @@ } }, "@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.1.tgz", + "integrity": "sha512-fEzPV3hSkSMltkw152tJKNARhOupqbH96MZWyRjNaYZOMIzbrTeQDG+MTc6Mr2pgzFQzFxAfmhGDNP5QK++2ZA==", "dev": true }, "@vitejs/plugin-vue": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.1.4.tgz", - "integrity": "sha512-N2XSI2n3sQqp5w7Y/AN/L2XDjBIRGqXko+eDp42sydYSBeJuSm5a1sLf8zakmo8u7tA8NmBgoDLA1HeOESjp9A==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.2.1.tgz", + "integrity": "sha512-cxh314tzaWwOLqVes2gnnCtvBDcM1UMdn+iFR+UjAn411dPT3tOmqrJjbMd7koZpMAmBM/GqeV4n9ge7JSiJJQ==", "dev": true, "requires": {} }, @@ -11544,12 +11218,12 @@ "dev": true }, "@vue/devtools-kit": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.5.2.tgz", - "integrity": "sha512-0leUOE2HBfl8sHf9ePKzxqnCFskkU22tWWqd9OfeSlslAKE30/TViYvWcF4vgQmPlJnAAdHU0WfW5dYlCeOiuw==", + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.6.8.tgz", + "integrity": "sha512-JhJ8M3sPU+v0P2iZBF2DkdmR9L0dnT5RXJabJqX6o8KtFs3tebdvfoXV2Dm3BFuqeECuMJIfF1aCzSt+WQ4wrw==", "dev": true, "requires": { - "@vue/devtools-shared": "^7.5.2", + "@vue/devtools-shared": "^7.6.8", "birpc": "^0.2.19", "hookable": "^5.5.3", "mitt": "^3.0.1", @@ -11559,9 +11233,9 @@ } }, "@vue/devtools-shared": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.5.2.tgz", - "integrity": "sha512-+zmcixnD6TAo+zwm30YuwZckhL9iIi4u+gFwbq9C8zpm3SMndTlEYZtNhAHUhOXB+bCkzyunxw80KQ/T0trF4w==", + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.6.8.tgz", + "integrity": "sha512-9MBPO5Z3X1nYGFqTJyohl6Gmf/J7UNN1oicHdyzBVZP4jnhZ4c20MgtaHDIzWmHDHCMYVS5bwKxT3jxh7gOOKA==", "dev": true, "requires": { "rfdc": "^1.4.1" @@ -11615,50 +11289,50 @@ "dev": true }, "@vuepress/bundler-vite": { - "version": "2.0.0-rc.18", - "resolved": "https://registry.npmjs.org/@vuepress/bundler-vite/-/bundler-vite-2.0.0-rc.18.tgz", - "integrity": "sha512-Q+OUul4OLIS4OLuKqIlmJKHhW5Edt5i6fVY6infgGhb4tUQt3z37DjCUtvbMikb05Va9YqtTAGt2eCWOk7eGPw==", + "version": "2.0.0-rc.19", + "resolved": "https://registry.npmjs.org/@vuepress/bundler-vite/-/bundler-vite-2.0.0-rc.19.tgz", + "integrity": "sha512-Vn0wEVRcdAld+8NJeELSwrj5JEPObRn0xpRWtAau/UwVWHmMLo16RRkTvXdjSiwpDWeP/9ztC5buyTXVoeb7Dw==", "dev": true, "requires": { - "@vitejs/plugin-vue": "^5.1.4", - "@vuepress/bundlerutils": "2.0.0-rc.18", - "@vuepress/client": "2.0.0-rc.18", - "@vuepress/core": "2.0.0-rc.18", - "@vuepress/shared": "2.0.0-rc.18", - "@vuepress/utils": "2.0.0-rc.18", + "@vitejs/plugin-vue": "^5.2.1", + "@vuepress/bundlerutils": "2.0.0-rc.19", + "@vuepress/client": "2.0.0-rc.19", + "@vuepress/core": "2.0.0-rc.19", + "@vuepress/shared": "2.0.0-rc.19", + "@vuepress/utils": "2.0.0-rc.19", "autoprefixer": "^10.4.20", "connect-history-api-fallback": "^2.0.0", - "postcss": "^8.4.47", + "postcss": "^8.4.49", "postcss-load-config": "^6.0.1", - "rollup": "^4.24.0", - "vite": "~5.4.8", - "vue": "^3.5.11", - "vue-router": "^4.4.5" + "rollup": "^4.28.1", + "vite": "~6.0.3", + "vue": "^3.5.13", + "vue-router": "^4.5.0" } }, "@vuepress/bundlerutils": { - "version": "2.0.0-rc.18", - "resolved": "https://registry.npmjs.org/@vuepress/bundlerutils/-/bundlerutils-2.0.0-rc.18.tgz", - "integrity": "sha512-GTcdc78cfcKqn/D3xPrxGFeR+WPV2zJE82jpKAnIa4I30aScq/95pYF1FofP0Gdc+0/XQCxFQ8xiT8iYcoQPSw==", + "version": "2.0.0-rc.19", + "resolved": "https://registry.npmjs.org/@vuepress/bundlerutils/-/bundlerutils-2.0.0-rc.19.tgz", + "integrity": "sha512-ln5htptK14OMJV3yeGRxAwYhSkVxrTwEHEaifeWrFvjuNxj2kLmkCl7MDdzr232jSOWwkCcmbOyafbxMsaRDkQ==", "dev": true, "requires": { - "@vuepress/client": "2.0.0-rc.18", - "@vuepress/core": "2.0.0-rc.18", - "@vuepress/shared": "2.0.0-rc.18", - "@vuepress/utils": "2.0.0-rc.18", - "vue": "^3.5.11", - "vue-router": "^4.4.5" + "@vuepress/client": "2.0.0-rc.19", + "@vuepress/core": "2.0.0-rc.19", + "@vuepress/shared": "2.0.0-rc.19", + "@vuepress/utils": "2.0.0-rc.19", + "vue": "^3.5.13", + "vue-router": "^4.5.0" } }, "@vuepress/cli": { - "version": "2.0.0-rc.18", - "resolved": "https://registry.npmjs.org/@vuepress/cli/-/cli-2.0.0-rc.18.tgz", - "integrity": "sha512-9Oxyb22klpBNzia+2D4NRGv+Jk0+TwHX8Pn25cy9TlyxMeh9+jFioXT0Jc3c9/vOesBaCI6JxSxwPqtgRFr1rQ==", + "version": "2.0.0-rc.19", + "resolved": "https://registry.npmjs.org/@vuepress/cli/-/cli-2.0.0-rc.19.tgz", + "integrity": "sha512-QFicPNIj3RZAJbHoLbeYlPJsPchnQLGuw0n8xv0eeUi9ejEXO1huWA8sLoPbTGdiDW+PHr1MHnaVMkyUfwaKcQ==", "dev": true, "requires": { - "@vuepress/core": "2.0.0-rc.18", - "@vuepress/shared": "2.0.0-rc.18", - "@vuepress/utils": "2.0.0-rc.18", + "@vuepress/core": "2.0.0-rc.19", + "@vuepress/shared": "2.0.0-rc.19", + "@vuepress/utils": "2.0.0-rc.19", "cac": "^6.7.14", "chokidar": "^3.6.0", "envinfo": "^7.14.0", @@ -11666,66 +11340,66 @@ } }, "@vuepress/client": { - "version": "2.0.0-rc.18", - "resolved": "https://registry.npmjs.org/@vuepress/client/-/client-2.0.0-rc.18.tgz", - "integrity": "sha512-ImeF10uwZvQt3KyYN+fdyPRCZmzEJ2r4sTxC/39ieVA4BzPpTzrJwBNT3KONYkckaoXnBXIoI8d+DWFfq9B9NQ==", + "version": "2.0.0-rc.19", + "resolved": "https://registry.npmjs.org/@vuepress/client/-/client-2.0.0-rc.19.tgz", + "integrity": "sha512-vUAU6n4qmtXqthxkb4LHq0D+VWSDenwBDf0jUs7RaBLuOVrbPtmH/hs4k1vLIlGdwC3Zs/G6tlB4UmuZiiwR8Q==", "dev": true, "requires": { - "@vue/devtools-api": "^7.4.6", - "@vuepress/shared": "2.0.0-rc.18", - "vue": "^3.5.11", - "vue-router": "^4.4.5" + "@vue/devtools-api": "^7.6.7", + "@vuepress/shared": "2.0.0-rc.19", + "vue": "^3.5.13", + "vue-router": "^4.5.0" }, "dependencies": { "@vue/devtools-api": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.5.2.tgz", - "integrity": "sha512-VxPbAQxJrYSIkoGVvQ2oOoKW8u4CMpvRLySTxhoJA38z8bQEGy9GO33eoRY/DulJbSFRfjZFNvH+dh8B4qpesQ==", + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.6.8.tgz", + "integrity": "sha512-ma6dY/sZR36zALVsV1W7eC57c6IJPXsy8SNgZn1PLVWU4z4dPn5TIBmnF4stmdJ4sQcixqKaQ8pwjbMPzEZwiA==", "dev": true, "requires": { - "@vue/devtools-kit": "^7.5.2" + "@vue/devtools-kit": "^7.6.8" } } } }, "@vuepress/core": { - "version": "2.0.0-rc.18", - "resolved": "https://registry.npmjs.org/@vuepress/core/-/core-2.0.0-rc.18.tgz", - "integrity": "sha512-ikQ5EyA1jZynk1amsihG0cX6kWTgCIsbGCBgPWDVfkSPCrYCxxaIfzvKgyGBiNBFZ7kqoxuMnEn8EaY/fhSL0A==", + "version": "2.0.0-rc.19", + "resolved": "https://registry.npmjs.org/@vuepress/core/-/core-2.0.0-rc.19.tgz", + "integrity": "sha512-rvmBPMIWS2dey/2QjxZoO0OcrUU46NE3mSLk3oU7JOP0cG7xvRxf6U1OXiwYLC3fPO4g6XbHiKe6gihkmL6VDA==", "dev": true, "requires": { - "@vuepress/client": "2.0.0-rc.18", - "@vuepress/markdown": "2.0.0-rc.18", - "@vuepress/shared": "2.0.0-rc.18", - "@vuepress/utils": "2.0.0-rc.18", - "vue": "^3.5.11" + "@vuepress/client": "2.0.0-rc.19", + "@vuepress/markdown": "2.0.0-rc.19", + "@vuepress/shared": "2.0.0-rc.19", + "@vuepress/utils": "2.0.0-rc.19", + "vue": "^3.5.13" } }, "@vuepress/helper": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/helper/-/helper-2.0.0-rc.56.tgz", - "integrity": "sha512-O4iGck8PnloYypgRx6w+Vc/yG7wi7pyli0FZo82LNx/6OmZAdilFUIacLO3Cr0HLmpX9sK6NzQJeJ4HAgsiIUw==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/helper/-/helper-2.0.0-rc.66.tgz", + "integrity": "sha512-T/1hzQwT1ShJDOgTvxUXt9Uydmik8cMnOAT6Bpv3OrmhyprSxJ4Riu1gYdn6W5VLf+MD9sUjTvwPAyixvwsI6w==", "dev": true, "requires": { - "@vue/shared": "^3.5.12", - "@vueuse/core": "^11.1.0", + "@vue/shared": "^3.5.13", + "@vueuse/core": "^12.0.0", "cheerio": "1.0.0", "fflate": "^0.8.2", "gray-matter": "^4.0.3", - "vue": "^3.5.12" + "vue": "^3.5.13" } }, "@vuepress/highlighter-helper": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/highlighter-helper/-/highlighter-helper-2.0.0-rc.56.tgz", - "integrity": "sha512-ol7bOQdg5/CxGYMCDV6ucQKT2AeJTLKc6I4OwzzMjkiBEH/u3PNyq5rDXFr6pgSmlboZ5Clx9H7aajXfYilY+w==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/highlighter-helper/-/highlighter-helper-2.0.0-rc.66.tgz", + "integrity": "sha512-RxhUIR+GFXXjCy5aFHHLvIKPcyyDhyzmka7shV+xr/vaU+EDbnQFrF67qo9pLDfzJc0KKTL9cKo4CcjkAoZ/tQ==", "dev": true, "requires": {} }, "@vuepress/markdown": { - "version": "2.0.0-rc.18", - "resolved": "https://registry.npmjs.org/@vuepress/markdown/-/markdown-2.0.0-rc.18.tgz", - "integrity": "sha512-RUX7rgjONBwOepWXqB4SzI2Tbm6zEYK2YTHwjexzAIBr+nxgB+B8nizdr+VvuVk7Ehn/CtcyXhBdf1NZh9UgUQ==", + "version": "2.0.0-rc.19", + "resolved": "https://registry.npmjs.org/@vuepress/markdown/-/markdown-2.0.0-rc.19.tgz", + "integrity": "sha512-6jgUXhpEK55PEEGtPhz7Hq/JqTbLU8n9w2D7emXiK2FYcbeKpjoRIbVRzmzB/dXeK3NzHChANu2IIqpOT6Ba1w==", "dev": true, "requires": { "@mdit-vue/plugin-component": "^2.1.3", @@ -11738,8 +11412,8 @@ "@mdit-vue/types": "^2.1.0", "@types/markdown-it": "^14.1.2", "@types/markdown-it-emoji": "^3.0.1", - "@vuepress/shared": "2.0.0-rc.18", - "@vuepress/utils": "2.0.0-rc.18", + "@vuepress/shared": "2.0.0-rc.19", + "@vuepress/utils": "2.0.0-rc.19", "markdown-it": "^14.1.0", "markdown-it-anchor": "^9.2.0", "markdown-it-emoji": "^3.0.0", @@ -11747,87 +11421,87 @@ } }, "@vuepress/plugin-active-header-links": { - "version": "2.0.0-rc.55", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-active-header-links/-/plugin-active-header-links-2.0.0-rc.55.tgz", - "integrity": "sha512-HwcvQpFhoyxURxalOO72L6cUM5yMcqKS/QFpaZvaob8pQBgZfJTH+77dfKEmz4rbf+WBMHrUEMfTICeJvu0Frw==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-active-header-links/-/plugin-active-header-links-2.0.0-rc.66.tgz", + "integrity": "sha512-3Rk5G8yheN14PQrFushePD+xLDnfmHCgxmPEtnF+9Sw1yfBSkYubpWy6NJLGW0zyPUaabTcoUXwNlzsf0swCKw==", "dev": true, "requires": { - "@vueuse/core": "^11.1.0", - "vue": "^3.5.12" + "@vueuse/core": "^12.0.0", + "vue": "^3.5.13" } }, "@vuepress/plugin-back-to-top": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-back-to-top/-/plugin-back-to-top-2.0.0-rc.56.tgz", - "integrity": "sha512-qlX/VHX3RRQnZIGrIqVNb+zwwPjV/9FMt8e/aITxp0gpaGaddOS8FFwVK8tOuKAJQVnq+QHJZtO+RdguS5216g==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-back-to-top/-/plugin-back-to-top-2.0.0-rc.66.tgz", + "integrity": "sha512-UeYLwjMV7zWbIR8iURDtzSfWQWKefSrYT/v6uo8XXhuC1U5IZD/MYlp+/H8EMQMYzmm4tqkbbsSSmlIdQBTpfw==", "dev": true, "requires": { - "@vuepress/helper": "2.0.0-rc.56", - "@vueuse/core": "^11.1.0", - "vue": "^3.5.12" + "@vuepress/helper": "2.0.0-rc.66", + "@vueuse/core": "^12.0.0", + "vue": "^3.5.13" } }, "@vuepress/plugin-blog": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-blog/-/plugin-blog-2.0.0-rc.56.tgz", - "integrity": "sha512-zV4zZ8tGvOaVNJGLswoDzCkzAx6lTjuGf51EM2qHGvRuGuc0vjuOb8vtDD4s7Idtjmiu4x/s+waPPy2r8Aalbw==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-blog/-/plugin-blog-2.0.0-rc.66.tgz", + "integrity": "sha512-Bbq8diNv/4TTftj8Ncc4Uc9PbL4t0pypP5j/uGL5eJZgqDVwKxGKTZ4dkM07U7j/dzIpPeKYnfxc0DIY9KYq/w==", "dev": true, "requires": { - "@vuepress/helper": "2.0.0-rc.56", + "@vuepress/helper": "2.0.0-rc.66", "chokidar": "^3.6.0", - "vue": "^3.5.12" + "vue": "^3.5.13" } }, "@vuepress/plugin-catalog": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-catalog/-/plugin-catalog-2.0.0-rc.56.tgz", - "integrity": "sha512-OsxujnVqQKyax+dC2QHTKdeO6aL62ZP1A7cgzBZDNIRGLYZjeTIypt2XT13OxisNm0pXzWBrqcv5zYQo+VvOrg==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-catalog/-/plugin-catalog-2.0.0-rc.66.tgz", + "integrity": "sha512-vIpfKnUJ2wtVk4JjLa7h91tN7LUi9rWTwrtiRCtUeRkkX9HX/VlxcnVFVIzClNwo0vTRuIVnMsIfKbta5QKZIw==", "dev": true, "requires": { - "@vuepress/helper": "2.0.0-rc.56", - "vue": "^3.5.12" + "@vuepress/helper": "2.0.0-rc.66", + "vue": "^3.5.13" } }, "@vuepress/plugin-comment": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-comment/-/plugin-comment-2.0.0-rc.56.tgz", - "integrity": "sha512-R26A434260YbYd6X5qdRo4CvW9/694+5us5NKFoiTo7HByx+4cblmddy5K6q40cfTcvbbnATVAUxVTDIPO7SFw==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-comment/-/plugin-comment-2.0.0-rc.66.tgz", + "integrity": "sha512-Rvr7EH7BTv1xSuUWoVWHj4iErSelDYgtKwkDQ2uJYVFwvV1y2ue5eInWSsCQdESZG52AbFO/UobQNbpCXp+v+A==", "dev": true, "requires": { - "@vuepress/helper": "2.0.0-rc.56", + "@vuepress/helper": "2.0.0-rc.66", "giscus": "^1.5.0", - "vue": "^3.5.12" + "vue": "^3.5.13" } }, "@vuepress/plugin-copy-code": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-copy-code/-/plugin-copy-code-2.0.0-rc.56.tgz", - "integrity": "sha512-f8lr7R66oOeH5WWuASwI683SPKmsH+6tCSrDc0fpRTprPIdKWMc7tbjMNLpzCDseqZUbvGGuBO7bl3LeIMSO4A==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-copy-code/-/plugin-copy-code-2.0.0-rc.66.tgz", + "integrity": "sha512-9z7R3d0qlQY5NnfsviqHRTVbjvq0n5ngdSpZc/yekl4/NmfgKqVuTqbFwirlj/vTcGqZwn2YfEu0v/nM3TLalA==", "dev": true, "requires": { - "@vuepress/helper": "2.0.0-rc.56", - "@vueuse/core": "^11.1.0", - "vue": "^3.5.12" + "@vuepress/helper": "2.0.0-rc.66", + "@vueuse/core": "^12.0.0", + "vue": "^3.5.13" } }, "@vuepress/plugin-copyright": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-copyright/-/plugin-copyright-2.0.0-rc.56.tgz", - "integrity": "sha512-4eLwtD4xOMLLxjkNBhJ9tLHEmCE4YKDRnRcdwc4OUzuCy8d/r+5Djwnv+sDDxqgNIZQISCd8UG0hFjwsOBx6Tg==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-copyright/-/plugin-copyright-2.0.0-rc.66.tgz", + "integrity": "sha512-B15VxyeUWMeUMRRnRWjaY1f81mPoJZvSW2otBy0zcFxfQ2IHvbRoy5nQL/s46bUhzdeVfCRNKKMYbqMofZa89A==", "dev": true, "requires": { - "@vuepress/helper": "2.0.0-rc.56", - "@vueuse/core": "^11.1.0", - "vue": "^3.5.12" + "@vuepress/helper": "2.0.0-rc.66", + "@vueuse/core": "^12.0.0", + "vue": "^3.5.13" } }, "@vuepress/plugin-git": { - "version": "2.0.0-rc.54", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-git/-/plugin-git-2.0.0-rc.54.tgz", - "integrity": "sha512-Yy0elQlKt+2GbeUI+mZMGdbkvCsPXep+lBLaXYQqiIcHC4tXAwj+1FwB18LTICiv3oQDHUtx7ZZwTnYejXJ7sg==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-git/-/plugin-git-2.0.0-rc.66.tgz", + "integrity": "sha512-GiAniZY/gI5u5La3/+qqKrDyYLZoEdE3N81buh4Nmf9K9RGSPw8mb/+XJ2q58zX8plPn925YXverfjkJLYxWyg==", "dev": true, "requires": { - "execa": "^9.4.0" + "execa": "^9.5.2" }, "dependencies": { "@sindresorhus/merge-streams": { @@ -11837,9 +11511,9 @@ "dev": true }, "execa": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-9.4.1.tgz", - "integrity": "sha512-5eo/BRqZm3GYce+1jqX/tJ7duA2AnE39i88fuedNFUV8XxGxUpF3aWkBRfbUcjV49gCkvS/pzc0YrCPhaIewdg==", + "version": "9.5.2", + "resolved": "https://registry.npmjs.org/execa/-/execa-9.5.2.tgz", + "integrity": "sha512-EHlpxMCpHWSAh1dgS6bVeoLAXGnJNdR93aabr4QCGbzOM73o5XmRfM/e5FUqsw3aagP8S8XEWUWFAxnRBnAF0Q==", "dev": true, "requires": { "@sindresorhus/merge-streams": "^4.0.0", @@ -11930,31 +11604,62 @@ } }, "@vuepress/plugin-links-check": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-links-check/-/plugin-links-check-2.0.0-rc.56.tgz", - "integrity": "sha512-5eyiI4zABfEyJ79xudilPx+jG4dhZ6ZQw7ZPs3nhsmpSsOsnbfBUjzRq0vYf5BVrSSmPIu9yFX+YcVZej2uvZg==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-links-check/-/plugin-links-check-2.0.0-rc.66.tgz", + "integrity": "sha512-B3xBdEjRMvhufLTSxLbWSRTKYsqnXWGZJSGZnk6mLzVdxmMXXHPacpaepF9WON26gUAnvWct7Uyg121l54aUSQ==", + "dev": true, + "requires": { + "@vuepress/helper": "2.0.0-rc.66" + } + }, + "@vuepress/plugin-markdown-ext": { + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-markdown-ext/-/plugin-markdown-ext-2.0.0-rc.66.tgz", + "integrity": "sha512-heSwOXrgh0hGDxDD6zCfi4xe1Uaz4GgguWdnWEMl1ewhssjjhC07be/FNt9wwWKjTJkkKHsdTUwyKV0R+mL3Gw==", "dev": true, "requires": { - "@vuepress/helper": "2.0.0-rc.56" + "@mdit/plugin-container": "^0.14.0", + "@mdit/plugin-footnote": "^0.14.0", + "@mdit/plugin-tasklist": "^0.14.0", + "@types/markdown-it": "^14.1.2", + "@vuepress/helper": "2.0.0-rc.66", + "js-yaml": "^4.1.0" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + } } }, "@vuepress/plugin-markdown-hint": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-markdown-hint/-/plugin-markdown-hint-2.0.0-rc.56.tgz", - "integrity": "sha512-qVOlqBIMjySormRde0uo/rILIC8BP59GIz+lRk8XpO5G92ejmJlRck27Pjrzm5NngR+pOonWfZ7yjGtT35U6nA==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-markdown-hint/-/plugin-markdown-hint-2.0.0-rc.66.tgz", + "integrity": "sha512-VZiZw+IexDe/+lgncmvbq8w+rwJCMYnTC181ZA5kIl5wiiOHY6U5gFdZ16TnlQB6MjARO8b2F5j+WDZTkS6J2w==", "dev": true, "requires": { - "@mdit/plugin-alert": "^0.13.1", - "@mdit/plugin-container": "^0.13.1", + "@mdit/plugin-alert": "^0.14.0", + "@mdit/plugin-container": "^0.14.0", "@types/markdown-it": "^14.1.2", - "@vuepress/helper": "2.0.0-rc.56", - "@vueuse/core": "^11.1.0" + "@vuepress/helper": "2.0.0-rc.66", + "@vueuse/core": "^12.0.0" } }, "@vuepress/plugin-markdown-image": { - "version": "2.0.0-rc.62", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-markdown-image/-/plugin-markdown-image-2.0.0-rc.62.tgz", - "integrity": "sha512-0fvGgj+iumJI0DezBfbCn0HglNhqQrObV6Gfou17U8k7FCZf8NoS4JgAd7Bj8PptGUbtaGnxiID54Hf0C9AKDw==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-markdown-image/-/plugin-markdown-image-2.0.0-rc.66.tgz", + "integrity": "sha512-+86SH1DRNB3Ek+L2deySlmW7HTBjLXFdLqxumry69NxzksHGFb03/1zKn48dfLVGceUX1339cQTf5RexSHEz0Q==", "dev": true, "requires": { "@mdit/plugin-figure": "^0.14.0", @@ -11962,7 +11667,7 @@ "@mdit/plugin-img-mark": "^0.14.0", "@mdit/plugin-img-size": "^0.14.0", "@types/markdown-it": "^14.1.2", - "@vuepress/helper": "2.0.0-rc.62" + "@vuepress/helper": "2.0.0-rc.66" }, "dependencies": { "@mdit/plugin-figure": { @@ -12000,72 +11705,59 @@ "requires": { "@types/markdown-it": "^14.1.2" } - }, - "@vuepress/helper": { - "version": "2.0.0-rc.62", - "resolved": "https://registry.npmjs.org/@vuepress/helper/-/helper-2.0.0-rc.62.tgz", - "integrity": "sha512-O6I9iliP1UxSI0g2PfLyx/WqvuKtGdcUl1DlxMQAw/YRfjbvcVIetV/htiUA3C8H5+RgJXvzRX/Zruik2aiuGg==", - "dev": true, - "requires": { - "@vue/shared": "^3.5.13", - "@vueuse/core": "^12.0.0", - "cheerio": "1.0.0", - "fflate": "^0.8.2", - "gray-matter": "^4.0.3", - "vue": "^3.5.13" - } - }, - "@vueuse/core": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-12.0.0.tgz", - "integrity": "sha512-C12RukhXiJCbx4MGhjmd/gH52TjJsc3G0E0kQj/kb19H3Nt6n1CA4DRWuTdWWcaFRdlTe0npWDS942mvacvNBw==", - "dev": true, - "requires": { - "@types/web-bluetooth": "^0.0.20", - "@vueuse/metadata": "12.0.0", - "@vueuse/shared": "12.0.0", - "vue": "^3.5.13" - } - }, - "@vueuse/metadata": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-12.0.0.tgz", - "integrity": "sha512-Yzimd1D3sjxTDOlF05HekU5aSGdKjxhuhRFHA7gDWLn57PRbBIh+SF5NmjhJ0WRgF3my7T8LBucyxdFJjIfRJQ==", - "dev": true - }, - "@vueuse/shared": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-12.0.0.tgz", - "integrity": "sha512-3i6qtcq2PIio5i/vVYidkkcgvmTjCqrf26u+Fd4LhnbBmIT6FN8y6q/GJERp8lfcB9zVEfjdV0Br0443qZuJpw==", - "dev": true, - "requires": { - "vue": "^3.5.13" - } } } }, - "@vuepress/plugin-markdown-math": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-markdown-math/-/plugin-markdown-math-2.0.0-rc.56.tgz", - "integrity": "sha512-I5+m+siib1m0+u9XCdmtGq2AyGg34l9HVAzCeJajVhA0/LUFdvqjxfVIg9ymuTqsspB8IW+x5O+acE6jznRdig==", + "@vuepress/plugin-markdown-include": { + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-markdown-include/-/plugin-markdown-include-2.0.0-rc.66.tgz", + "integrity": "sha512-B3dlrQNbU1ItOsWR7QOyZ4yfPfzzZ88ri0ORQCocq0Q6oJGSI6kUoPs9yOBrfW6chNuPc+IdJgqgHpWWu9Lp7A==", + "dev": true, + "requires": { + "@mdit/plugin-include": "^0.14.0", + "@types/markdown-it": "^14.1.2", + "@vuepress/helper": "2.0.0-rc.66" + } + }, + "@vuepress/plugin-markdown-math": { + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-markdown-math/-/plugin-markdown-math-2.0.0-rc.66.tgz", + "integrity": "sha512-X9N6IlgZfivJKv43j7Kpya2BHQs3U969FMvZNhSJmIrloqhAWlBPA6O97cL+P4jnid/obfp585rz9Ecc1/Qx1w==", + "dev": true, + "requires": { + "@mdit/plugin-katex-slim": "^0.14.0", + "@mdit/plugin-mathjax-slim": "^0.14.0", + "@types/markdown-it": "^14.1.2", + "@vuepress/helper": "2.0.0-rc.66", + "vue": "^3.5.13" + } + }, + "@vuepress/plugin-markdown-stylize": { + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-markdown-stylize/-/plugin-markdown-stylize-2.0.0-rc.66.tgz", + "integrity": "sha512-e8JoHkILmVcq0DMWbDVrHg7SuphHPA6kIRgk01khK2c9b2BFAEd7T4xjpcp/ISfbebc0PA7F0z3z6IVT/vfwJQ==", "dev": true, "requires": { - "@mdit/plugin-katex-slim": "^0.13.1", - "@mdit/plugin-mathjax-slim": "^0.13.1", + "@mdit/plugin-align": "^0.14.0", + "@mdit/plugin-attrs": "^0.14.0", + "@mdit/plugin-mark": "^0.14.0", + "@mdit/plugin-spoiler": "^0.14.0", + "@mdit/plugin-stylize": "^0.14.0", + "@mdit/plugin-sub": "^0.14.0", + "@mdit/plugin-sup": "^0.14.0", "@types/markdown-it": "^14.1.2", - "@vuepress/helper": "2.0.0-rc.56", - "vue": "^3.5.12" + "@vuepress/helper": "2.0.0-rc.66" } }, "@vuepress/plugin-markdown-tab": { - "version": "2.0.0-rc.62", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-markdown-tab/-/plugin-markdown-tab-2.0.0-rc.62.tgz", - "integrity": "sha512-rjIZ5P6unPMcuLktVJlsqaU6VnrSa+n/phxCrWzZ4dBLUNjbDEqPB6YnrBgiO4dZzLeLVqpE2dqWMiuK0CbRjg==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-markdown-tab/-/plugin-markdown-tab-2.0.0-rc.66.tgz", + "integrity": "sha512-QpZAM8YuqVPzQRtEBne+MxDtrlrXQFhQe5xkL8FUvqdxAenQqb6IfK413rsay91tfLE88i9xcJSIjU3ikSl/Kg==", "dev": true, "requires": { "@mdit/plugin-tab": "^0.14.0", "@types/markdown-it": "^14.1.2", - "@vuepress/helper": "2.0.0-rc.62", + "@vuepress/helper": "2.0.0-rc.66", "@vueuse/core": "^12.0.0", "vue": "^3.5.13" }, @@ -12079,122 +11771,81 @@ "@mdit/helper": "0.14.0", "@types/markdown-it": "^14.1.2" } - }, - "@vuepress/helper": { - "version": "2.0.0-rc.62", - "resolved": "https://registry.npmjs.org/@vuepress/helper/-/helper-2.0.0-rc.62.tgz", - "integrity": "sha512-O6I9iliP1UxSI0g2PfLyx/WqvuKtGdcUl1DlxMQAw/YRfjbvcVIetV/htiUA3C8H5+RgJXvzRX/Zruik2aiuGg==", - "dev": true, - "requires": { - "@vue/shared": "^3.5.13", - "@vueuse/core": "^12.0.0", - "cheerio": "1.0.0", - "fflate": "^0.8.2", - "gray-matter": "^4.0.3", - "vue": "^3.5.13" - } - }, - "@vueuse/core": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-12.0.0.tgz", - "integrity": "sha512-C12RukhXiJCbx4MGhjmd/gH52TjJsc3G0E0kQj/kb19H3Nt6n1CA4DRWuTdWWcaFRdlTe0npWDS942mvacvNBw==", - "dev": true, - "requires": { - "@types/web-bluetooth": "^0.0.20", - "@vueuse/metadata": "12.0.0", - "@vueuse/shared": "12.0.0", - "vue": "^3.5.13" - } - }, - "@vueuse/metadata": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-12.0.0.tgz", - "integrity": "sha512-Yzimd1D3sjxTDOlF05HekU5aSGdKjxhuhRFHA7gDWLn57PRbBIh+SF5NmjhJ0WRgF3my7T8LBucyxdFJjIfRJQ==", - "dev": true - }, - "@vueuse/shared": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-12.0.0.tgz", - "integrity": "sha512-3i6qtcq2PIio5i/vVYidkkcgvmTjCqrf26u+Fd4LhnbBmIT6FN8y6q/GJERp8lfcB9zVEfjdV0Br0443qZuJpw==", - "dev": true, - "requires": { - "vue": "^3.5.13" - } } } }, "@vuepress/plugin-notice": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-notice/-/plugin-notice-2.0.0-rc.56.tgz", - "integrity": "sha512-qSJ5PrGTVvRhSeyIXRz7cBFZ0nQ6J9tXSIsie7K31NuXDYqq6gOX6nT6uARvHgJwcX0ah9hcLovSVqJomkeSsA==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-notice/-/plugin-notice-2.0.0-rc.66.tgz", + "integrity": "sha512-tYySrJYoX/RMGF7YmQSqKIttWnbtraCy0r5lr+8EmOsLxUwPJqD52rXKlfxaIjMGjGoyYx0WzUpy5Txm9PPPeg==", "dev": true, "requires": { - "@vuepress/helper": "2.0.0-rc.56", - "@vueuse/core": "^11.1.0", - "vue": "^3.5.12" + "@vuepress/helper": "2.0.0-rc.66", + "@vueuse/core": "^12.0.0", + "vue": "^3.5.13" } }, "@vuepress/plugin-nprogress": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-nprogress/-/plugin-nprogress-2.0.0-rc.56.tgz", - "integrity": "sha512-U0KxEvDDk5r2+B8SVsrEu7gFzz3vs8K5bVlUQiyEQ5vdE1aKIUjA/hQwq/gWy76qmOIVlHlKZnOB5C+w4At0SA==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-nprogress/-/plugin-nprogress-2.0.0-rc.66.tgz", + "integrity": "sha512-nVjZjxeeGbFk0AsugMX5Y2dgATfMTO0Hvb3JaOH1ee8H06Ia3A0eCYBwzOs/eP/F1lYx934PJS3aRqnkx2f+mg==", "dev": true, "requires": { - "@vuepress/helper": "2.0.0-rc.56", - "vue": "^3.5.12" + "@vuepress/helper": "2.0.0-rc.66", + "vue": "^3.5.13" } }, "@vuepress/plugin-photo-swipe": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-photo-swipe/-/plugin-photo-swipe-2.0.0-rc.56.tgz", - "integrity": "sha512-/XBmWwmrrctO/M7AceFJLFMrjdpnDBPyKN1w/ecJr75AEPBYhntoXZdB+AOgRvHswhP2XUUiku6zrXx10zdO6g==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-photo-swipe/-/plugin-photo-swipe-2.0.0-rc.66.tgz", + "integrity": "sha512-lKF0yFYAJ6lhg6+/ud2CukOznMV3G8ZivZIAIG79YrM27FeFG0QznXVYdWmA/76sPu83gGQEQLFM6DyDHgkhEg==", "dev": true, "requires": { - "@vuepress/helper": "2.0.0-rc.56", - "@vueuse/core": "^11.1.0", + "@vuepress/helper": "2.0.0-rc.66", + "@vueuse/core": "^12.0.0", "photoswipe": "^5.4.4", - "vue": "^3.5.12" + "vue": "^3.5.13" } }, "@vuepress/plugin-reading-time": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-reading-time/-/plugin-reading-time-2.0.0-rc.56.tgz", - "integrity": "sha512-69JJTZUd9lb2aq9VII19+Y9nPRjiRi0sclEboGpvy7P4JabPKu4AiLh1L/OPBzpXsxZuMmz+EDErOUozL3eSGw==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-reading-time/-/plugin-reading-time-2.0.0-rc.66.tgz", + "integrity": "sha512-42T9i+oqqCkBXlYmoEWEW0miX3Ypubyw+0OdOSEpKm3LioDnIL9l+GmgyBy2VRqin3foerNJCwDqUMoa2Jxb8w==", "dev": true, "requires": { - "@vuepress/helper": "2.0.0-rc.56", - "vue": "^3.5.12" + "@vuepress/helper": "2.0.0-rc.66", + "vue": "^3.5.13" } }, "@vuepress/plugin-redirect": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-redirect/-/plugin-redirect-2.0.0-rc.56.tgz", - "integrity": "sha512-MmiZGMTQwCtdBGapII3u0iG8C9Y36eH15Pzt2G5Auwzp9X9LL/TLmuN2K0/ckjqkWj0j7ei6to4k0/TFEjSKbw==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-redirect/-/plugin-redirect-2.0.0-rc.66.tgz", + "integrity": "sha512-fY1R6NI7coEqeBaCyfV7ETZUymUnheykenDAvZJf90I62sWYBRd27sKYQWNpobOmXKqRzyx/WFyixbfiBYrWLQ==", "dev": true, "requires": { - "@vuepress/helper": "2.0.0-rc.56", - "@vueuse/core": "^11.1.0", + "@vuepress/helper": "2.0.0-rc.66", + "@vueuse/core": "^12.0.0", "cac": "^6.7.14", - "vue": "^3.5.12" + "vue": "^3.5.13" } }, "@vuepress/plugin-rtl": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-rtl/-/plugin-rtl-2.0.0-rc.56.tgz", - "integrity": "sha512-qlN5FcIl1pdCjadqiYCy96zObZ18m6FyzEp22MPgZmvKYgHR5N2BPzV98wQYSICx0Fz1lYftQFgqNnmrCqB5OQ==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-rtl/-/plugin-rtl-2.0.0-rc.66.tgz", + "integrity": "sha512-OzIwtq/6a37qJXYsOMhqm0PZPRNgu0+CPnkjW71jPZlBaqyb7D6NJOCDuBncVyVDR8uC7OJbaCHT8otJvOWrig==", "dev": true, "requires": { - "@vuepress/helper": "2.0.0-rc.56", - "vue": "^3.5.12" + "@vuepress/helper": "2.0.0-rc.66", + "vue": "^3.5.13" } }, "@vuepress/plugin-sass-palette": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-sass-palette/-/plugin-sass-palette-2.0.0-rc.56.tgz", - "integrity": "sha512-gGA/CidSaOGiuskWKPsUGFVgiv3xEZAQDMRUaAgeMdvObJ70/wYO09uPaTu56mesrpc9P+FBMH67sdTQfHietQ==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-sass-palette/-/plugin-sass-palette-2.0.0-rc.66.tgz", + "integrity": "sha512-ghMAGK+nRyLmTssppOYcF3N4hsVrM+4H88WKNM6u9QwGx0EyzC/tEEL0CE3QwgJMMt6FKVGsHwDC64Mz/j2a3g==", "dev": true, "requires": { - "@vuepress/helper": "2.0.0-rc.56", + "@vuepress/helper": "2.0.0-rc.66", "chokidar": "^4.0.1" }, "dependencies": { @@ -12216,148 +11867,130 @@ } }, "@vuepress/plugin-seo": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-seo/-/plugin-seo-2.0.0-rc.56.tgz", - "integrity": "sha512-s1DyQA7umBlzPKbehiey5xk5w2ANlkifeYd26sj5ReRF8J6k0ZxdN6ahyBqxm9TPd8+69yW8GYZq0OXrh0qv9Q==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-seo/-/plugin-seo-2.0.0-rc.66.tgz", + "integrity": "sha512-DqOrTnF3r6RBlQvENRejYKGPcdOBXo7gzYha2NtRtgMzxPjCZM9oom6jd8ew1VLuM0JhDoLG9AfUjgnRVrpM0w==", "dev": true, "requires": { - "@vuepress/helper": "2.0.0-rc.56" + "@vuepress/helper": "2.0.0-rc.66" } }, "@vuepress/plugin-shiki": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-shiki/-/plugin-shiki-2.0.0-rc.56.tgz", - "integrity": "sha512-IQHz7SVZ1zqqryBBqjPvNI32wub7JPsnSoR+X5VoQR4Ncs5i13+sOndZVHDUZMdpfwuKej50ZNW2SioTqN3ngA==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-shiki/-/plugin-shiki-2.0.0-rc.66.tgz", + "integrity": "sha512-yq54ry9P8/xQP/eUZvctko/zhGsTPLywhN538ttOospog0Lh8u/m9aNra3sRuGNHBOeF4oyKJ3VyQfb9gfHmZg==", "dev": true, "requires": { - "@shikijs/transformers": "^1.22.0", - "@vuepress/helper": "2.0.0-rc.56", - "@vuepress/highlighter-helper": "2.0.0-rc.56", - "nanoid": "^5.0.7", - "shiki": "^1.22.0" + "@shikijs/transformers": "^1.24.2", + "@vuepress/helper": "2.0.0-rc.66", + "@vuepress/highlighter-helper": "2.0.0-rc.66", + "nanoid": "^5.0.9", + "shiki": "^1.24.2" }, "dependencies": { "nanoid": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.7.tgz", - "integrity": "sha512-oLxFY2gd2IqnjcYyOXD8XGCftpGtZP2AbHbOkthDkvRywH5ayNtPVy9YlOPcHckXzbLTCHpkb7FB+yuxKV13pQ==", + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.9.tgz", + "integrity": "sha512-Aooyr6MXU6HpvvWXKoVoXwKMs/KyVakWwg7xQfv5/S/RIgJMy0Ifa45H9qqYy7pTCszrHzP21Uk4PZq2HpEM8Q==", "dev": true } } }, "@vuepress/plugin-sitemap": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-sitemap/-/plugin-sitemap-2.0.0-rc.56.tgz", - "integrity": "sha512-zEhsQQ5YSfdvywQxn9PhjzNB5QDOBT5/9wmUsuaBT/feDW6vII3OCoj/Z5+lz2kfmL67qjqswmqklF84v2PbRQ==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-sitemap/-/plugin-sitemap-2.0.0-rc.66.tgz", + "integrity": "sha512-1SbnuyUj/6CId4SDMCPlFEJPjNdXgcPZS+iWNLGiAe6NuTrMeFRSJ/huZDphtJnfL20TboVrMowExpzKR2GoAg==", "dev": true, "requires": { - "@vuepress/helper": "2.0.0-rc.56", + "@vuepress/helper": "2.0.0-rc.66", "sitemap": "^8.0.0" } }, "@vuepress/plugin-theme-data": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-theme-data/-/plugin-theme-data-2.0.0-rc.56.tgz", - "integrity": "sha512-FccAdVbPxtXgdfOhCT1spNVDv/WfveTcDJ4FFZURf6YqJ9LflIhPpFIcRtE3XUD5HBEC4vvxuJCRxWOesM1LVQ==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-theme-data/-/plugin-theme-data-2.0.0-rc.66.tgz", + "integrity": "sha512-zCojGjYuQo/EXeF4cXA99ubxE7TUNDopMUGIjKKJjpDs1me6zkXSj1NqKnUD3+uHpP0PP7YXfROxTlk6Fy+FGg==", "dev": true, "requires": { - "@vue/devtools-api": "^7.5.2", - "vue": "^3.5.12" + "@vue/devtools-api": "^7.6.8", + "vue": "^3.5.13" }, "dependencies": { "@vue/devtools-api": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.5.2.tgz", - "integrity": "sha512-VxPbAQxJrYSIkoGVvQ2oOoKW8u4CMpvRLySTxhoJA38z8bQEGy9GO33eoRY/DulJbSFRfjZFNvH+dh8B4qpesQ==", + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.6.8.tgz", + "integrity": "sha512-ma6dY/sZR36zALVsV1W7eC57c6IJPXsy8SNgZn1PLVWU4z4dPn5TIBmnF4stmdJ4sQcixqKaQ8pwjbMPzEZwiA==", "dev": true, "requires": { - "@vue/devtools-kit": "^7.5.2" + "@vue/devtools-kit": "^7.6.8" } } } }, "@vuepress/plugin-watermark": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-watermark/-/plugin-watermark-2.0.0-rc.56.tgz", - "integrity": "sha512-u2rWJhODTs++77e2mdrSRxUOD9qUMJZrhyhBjrXprfGfOmvo7CE54NoR8oznKxEa7JSfGaibDWVIqgHvOLlm7g==", + "version": "2.0.0-rc.66", + "resolved": "https://registry.npmjs.org/@vuepress/plugin-watermark/-/plugin-watermark-2.0.0-rc.66.tgz", + "integrity": "sha512-QaC7v/s/kUvO7rMzoyE3V4VPXDQarMUNEBVbSi4k/ghJxCyyO57GxlB2P+5ZLgp5P3frmecGd/BJ0lNUFPbR3g==", "dev": true, "requires": { - "@vuepress/helper": "2.0.0-rc.56", - "vue": "^3.5.12", + "@vuepress/helper": "2.0.0-rc.66", + "vue": "^3.5.13", "watermark-js-plus": "^1.5.7" } }, "@vuepress/shared": { - "version": "2.0.0-rc.18", - "resolved": "https://registry.npmjs.org/@vuepress/shared/-/shared-2.0.0-rc.18.tgz", - "integrity": "sha512-um5/ZKGOKgaui5Xo1aRSZ3ko7zVq60k1M8j8ajEOu90LUD1e8glTa7Km9OIBgPcN+yx2OrNwuu8ieEupdNAm4w==", + "version": "2.0.0-rc.19", + "resolved": "https://registry.npmjs.org/@vuepress/shared/-/shared-2.0.0-rc.19.tgz", + "integrity": "sha512-xaDeZxX0Qetc2Y6/lrzO6M/40i3LmMm7Fk85bOftBBOaNehZ24RdsmIHBJDDv+bTUv+DBF++1/mOtbt6DBRzEA==", "dev": true, "requires": { "@mdit-vue/types": "^2.1.0" } }, "@vuepress/utils": { - "version": "2.0.0-rc.18", - "resolved": "https://registry.npmjs.org/@vuepress/utils/-/utils-2.0.0-rc.18.tgz", - "integrity": "sha512-0+5vrv3CBycWpAahmutEK2iyuc9oL6JOWMuAdh+cYuuHt1vX+LHfhWGvSep+UT6pOFGOcZfQzXSdlbkv3b4j+Q==", + "version": "2.0.0-rc.19", + "resolved": "https://registry.npmjs.org/@vuepress/utils/-/utils-2.0.0-rc.19.tgz", + "integrity": "sha512-cgzk8/aJquZKgFMNTuqdjbU5NrCzrPmdTyhYBcmliL/6N/He1OTWn3PD9QWUGJNODb1sPRJpklZnCpU07waLmg==", "dev": true, "requires": { "@types/debug": "^4.1.12", "@types/fs-extra": "^11.0.4", "@types/hash-sum": "^1.0.2", - "@vuepress/shared": "2.0.0-rc.18", - "debug": "^4.3.7", + "@vuepress/shared": "2.0.0-rc.19", + "debug": "^4.4.0", "fs-extra": "^11.2.0", "globby": "^14.0.2", "hash-sum": "^2.0.0", - "ora": "^8.1.0", - "picocolors": "^1.1.0", + "ora": "^8.1.1", + "picocolors": "^1.1.1", "upath": "^2.0.1" } }, "@vueuse/core": { - "version": "11.3.0", - "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-11.3.0.tgz", - "integrity": "sha512-7OC4Rl1f9G8IT6rUfi9JrKiXy4bfmHhZ5x2Ceojy0jnd3mHNEvV4JaRygH362ror6/NZ+Nl+n13LPzGiPN8cKA==", + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-12.0.0.tgz", + "integrity": "sha512-C12RukhXiJCbx4MGhjmd/gH52TjJsc3G0E0kQj/kb19H3Nt6n1CA4DRWuTdWWcaFRdlTe0npWDS942mvacvNBw==", "dev": true, "requires": { "@types/web-bluetooth": "^0.0.20", - "@vueuse/metadata": "11.3.0", - "@vueuse/shared": "11.3.0", - "vue-demi": ">=0.14.10" - }, - "dependencies": { - "vue-demi": { - "version": "0.14.10", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz", - "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", - "dev": true, - "requires": {} - } + "@vueuse/metadata": "12.0.0", + "@vueuse/shared": "12.0.0", + "vue": "^3.5.13" } }, "@vueuse/metadata": { - "version": "11.3.0", - "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-11.3.0.tgz", - "integrity": "sha512-pwDnDspTqtTo2HwfLw4Rp6yywuuBdYnPYDq+mO38ZYKGebCUQC/nVj/PXSiK9HX5otxLz8Fn7ECPbjiRz2CC3g==", + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-12.0.0.tgz", + "integrity": "sha512-Yzimd1D3sjxTDOlF05HekU5aSGdKjxhuhRFHA7gDWLn57PRbBIh+SF5NmjhJ0WRgF3my7T8LBucyxdFJjIfRJQ==", "dev": true }, "@vueuse/shared": { - "version": "11.3.0", - "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-11.3.0.tgz", - "integrity": "sha512-P8gSSWQeucH5821ek2mn/ciCk+MS/zoRKqdQIM3bHq6p7GXDAJLmnRRKmF5F65sAVJIfzQlwR3aDzwCn10s8hA==", + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-12.0.0.tgz", + "integrity": "sha512-3i6qtcq2PIio5i/vVYidkkcgvmTjCqrf26u+Fd4LhnbBmIT6FN8y6q/GJERp8lfcB9zVEfjdV0Br0443qZuJpw==", "dev": true, "requires": { - "vue-demi": ">=0.14.10" - }, - "dependencies": { - "vue-demi": { - "version": "0.14.10", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz", - "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", - "dev": true, - "requires": {} - } + "vue": "^3.5.13" } }, "acorn": { @@ -12543,9 +12176,9 @@ } }, "bcrypt-ts": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-ts/-/bcrypt-ts-5.0.2.tgz", - "integrity": "sha512-gDwQ5784AkkfhHACh3jGcg1hUubyZyeq9AtVd5gXkcyHGVOC+mORjRIHSj+fHfqwY5vxwyBLXQpcfk8MpK0ROg==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/bcrypt-ts/-/bcrypt-ts-5.0.3.tgz", + "integrity": "sha512-2FcgD12xPbwCoe5i9/HK0jJ1xA1m+QfC1e6htG9Bl/hNOnLyaFmQSlqLKcfe3QdnoMPKpKEGFCbESBTg+SJNOw==", "dev": true }, "binary-extensions": { @@ -12615,14 +12248,6 @@ "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", "dev": true }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true, - "optional": true, - "peer": true - }, "cac": { "version": "6.7.14", "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", @@ -13605,6 +13230,12 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "emoji-regex-xs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex-xs/-/emoji-regex-xs-1.0.0.tgz", + "integrity": "sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==", + "dev": true + }, "encoding-sniffer": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.0.tgz", @@ -14106,9 +13737,9 @@ } }, "hast-util-to-html": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.3.tgz", - "integrity": "sha512-M17uBDzMJ9RPCqLMO92gNNUDuBSq10a25SDBI08iCCxmorf4Yy6sYHK57n9WAbRAAaU+DuR4W6GN9K4DFZesYg==", + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.4.tgz", + "integrity": "sha512-wxQzXtdbhiwGAUKrnQJXlOPmHnEehzphwkK7aluUPQ+lEc1xefC8pblMgpp2w5ldBTEfveRIrADcrhGIWrlTDA==", "dev": true, "requires": { "@types/hast": "^3.0.0", @@ -14196,9 +13827,9 @@ "dev": true }, "immutable": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz", - "integrity": "sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.0.3.tgz", + "integrity": "sha512-P8IdPQHq3lA1xVeBRi5VPqUm5HDgKnx0Ru51wZz5mjxHr5n3RWhjIpOFU7ybkUxfB+5IToy+OLaHYDBIWsv+uw==", "dev": true, "optional": true, "peer": true @@ -14458,107 +14089,6 @@ "integrity": "sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==", "dev": true }, - "lightningcss": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.27.0.tgz", - "integrity": "sha512-8f7aNmS1+etYSLHht0fQApPc2kNO8qGRutifN5rVIc6Xo6ABsEbqOr758UwI7ALVbTt4x1fllKt0PYgzD9S3yQ==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "detect-libc": "^1.0.3", - "lightningcss-darwin-arm64": "1.27.0", - "lightningcss-darwin-x64": "1.27.0", - "lightningcss-freebsd-x64": "1.27.0", - "lightningcss-linux-arm-gnueabihf": "1.27.0", - "lightningcss-linux-arm64-gnu": "1.27.0", - "lightningcss-linux-arm64-musl": "1.27.0", - "lightningcss-linux-x64-gnu": "1.27.0", - "lightningcss-linux-x64-musl": "1.27.0", - "lightningcss-win32-arm64-msvc": "1.27.0", - "lightningcss-win32-x64-msvc": "1.27.0" - } - }, - "lightningcss-darwin-arm64": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.27.0.tgz", - "integrity": "sha512-Gl/lqIXY+d+ySmMbgDf0pgaWSqrWYxVHoc88q+Vhf2YNzZ8DwoRzGt5NZDVqqIW5ScpSnmmjcgXP87Dn2ylSSQ==", - "dev": true, - "optional": true, - "peer": true - }, - "lightningcss-darwin-x64": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.27.0.tgz", - "integrity": "sha512-0+mZa54IlcNAoQS9E0+niovhyjjQWEMrwW0p2sSdLRhLDc8LMQ/b67z7+B5q4VmjYCMSfnFi3djAAQFIDuj/Tg==", - "dev": true, - "optional": true, - "peer": true - }, - "lightningcss-freebsd-x64": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.27.0.tgz", - "integrity": "sha512-n1sEf85fePoU2aDN2PzYjoI8gbBqnmLGEhKq7q0DKLj0UTVmOTwDC7PtLcy/zFxzASTSBlVQYJUhwIStQMIpRA==", - "dev": true, - "optional": true, - "peer": true - }, - "lightningcss-linux-arm-gnueabihf": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.27.0.tgz", - "integrity": "sha512-MUMRmtdRkOkd5z3h986HOuNBD1c2lq2BSQA1Jg88d9I7bmPGx08bwGcnB75dvr17CwxjxD6XPi3Qh8ArmKFqCA==", - "dev": true, - "optional": true, - "peer": true - }, - "lightningcss-linux-arm64-gnu": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.27.0.tgz", - "integrity": "sha512-cPsxo1QEWq2sfKkSq2Bq5feQDHdUEwgtA9KaB27J5AX22+l4l0ptgjMZZtYtUnteBofjee+0oW1wQ1guv04a7A==", - "dev": true, - "optional": true, - "peer": true - }, - "lightningcss-linux-arm64-musl": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.27.0.tgz", - "integrity": "sha512-rCGBm2ax7kQ9pBSeITfCW9XSVF69VX+fm5DIpvDZQl4NnQoMQyRwhZQm9pd59m8leZ1IesRqWk2v/DntMo26lg==", - "dev": true, - "optional": true, - "peer": true - }, - "lightningcss-linux-x64-gnu": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.27.0.tgz", - "integrity": "sha512-Dk/jovSI7qqhJDiUibvaikNKI2x6kWPN79AQiD/E/KeQWMjdGe9kw51RAgoWFDi0coP4jinaH14Nrt/J8z3U4A==", - "dev": true, - "optional": true, - "peer": true - }, - "lightningcss-linux-x64-musl": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.27.0.tgz", - "integrity": "sha512-QKjTxXm8A9s6v9Tg3Fk0gscCQA1t/HMoF7Woy1u68wCk5kS4fR+q3vXa1p3++REW784cRAtkYKrPy6JKibrEZA==", - "dev": true, - "optional": true, - "peer": true - }, - "lightningcss-win32-arm64-msvc": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.27.0.tgz", - "integrity": "sha512-/wXegPS1hnhkeG4OXQKEMQeJd48RDC3qdh+OA8pCuOPCyvnm/yEayrJdJVqzBsqpy1aJklRCVxscpFur80o6iQ==", - "dev": true, - "optional": true, - "peer": true - }, - "lightningcss-win32-x64-msvc": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.27.0.tgz", - "integrity": "sha512-/OJLj94Zm/waZShL8nB5jsNj3CfNATLCTyFxZyouilfTmSoLDX7VlVAmhPHoZWVFp4vdmoiEbPEYC8HID3m6yw==", - "dev": true, - "optional": true, - "peer": true - }, "lilconfig": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", @@ -14832,9 +14362,9 @@ } }, "micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "dev": true, "requires": { "micromark-util-symbol": "^2.0.0", @@ -14842,15 +14372,15 @@ } }, "micromark-util-encode": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", - "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", "dev": true }, "micromark-util-sanitize-uri": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", - "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", "dev": true, "requires": { "micromark-util-character": "^2.0.0", @@ -14859,15 +14389,15 @@ } }, "micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "dev": true }, "micromark-util-types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", - "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.1.tgz", + "integrity": "sha512-534m2WhVTddrcKVepwmVEVnUAmtrx9bfIjNoQHRqfnvdaHQiFytEhJoTgpWJvDEXCO5gLTQh3wYC1PgOJA4NSQ==", "dev": true }, "micromatch": { @@ -15011,19 +14541,21 @@ "mimic-fn": "^2.1.0" } }, - "oniguruma-to-js": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/oniguruma-to-js/-/oniguruma-to-js-0.4.3.tgz", - "integrity": "sha512-X0jWUcAlxORhOqqBREgPMgnshB7ZGYszBNspP+tS9hPD3l13CdaXcHbgImoHUHlrvGx/7AvFEkTRhAGYh+jzjQ==", + "oniguruma-to-es": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-0.7.0.tgz", + "integrity": "sha512-HRaRh09cE0gRS3+wi2zxekB+I5L8C/gN60S+vb11eADHUaB/q4u8wGGOX3GvwvitG8ixaeycZfeoyruKQzUgNg==", "dev": true, "requires": { - "regex": "^4.3.2" + "emoji-regex-xs": "^1.0.0", + "regex": "^5.0.2", + "regex-recursion": "^4.3.0" } }, "ora": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/ora/-/ora-8.1.0.tgz", - "integrity": "sha512-GQEkNkH/GHOhPFXcqZs3IDahXEQcQxsSjEkK4KvEEST4t7eNzoMjxTzef+EZ+JluDEV+Raoi3WQ2CflnRdSVnQ==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-8.1.1.tgz", + "integrity": "sha512-YWielGi1XzG1UTvOaCFaNgEnuhZVMSHYkW/FQ7UX8O26PtlpdM84c0f7wLPlkvx2RfiQmnzd61d/MGxmpQeJPw==", "dev": true, "requires": { "chalk": "^5.3.0", @@ -15361,9 +14893,9 @@ "dev": true }, "pretty-ms": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.1.0.tgz", - "integrity": "sha512-o1piW0n3tgKIKCwk2vpM/vOV13zjJzvP37Ioze54YlTHE06m4tjEbzg9WsKkvTuyYln2DHjo5pY4qrZGI0otpw==", + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.2.0.tgz", + "integrity": "sha512-4yf0QO/sllf/1zbZWYnvWw3NxCQwLXKzIj0G849LSufP15BXKM0rbD2Z3wVnkMfjdn/CB0Dpp444gYAACdsplg==", "dev": true, "requires": { "parse-ms": "^4.0.0" @@ -15457,9 +14989,27 @@ } }, "regex": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/regex/-/regex-4.3.3.tgz", - "integrity": "sha512-r/AadFO7owAq1QJVeZ/nq9jNS1vyZt+6t1p/E59B56Rn2GCya+gr1KSyOzNL/er+r+B7phv5jG2xU2Nz1YkmJg==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/regex/-/regex-5.0.2.tgz", + "integrity": "sha512-/pczGbKIQgfTMRV0XjABvc5RzLqQmwqxLHdQao2RTXPk+pmTXB2P0IaUHYdYyk412YLwUIkaeMd5T+RzVgTqnQ==", + "dev": true, + "requires": { + "regex-utilities": "^2.3.0" + } + }, + "regex-recursion": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/regex-recursion/-/regex-recursion-4.3.0.tgz", + "integrity": "sha512-5LcLnizwjcQ2ALfOj95MjcatxyqF5RPySx9yT+PaXu3Gox2vyAtLDjHB8NTJLtMGkvyau6nI3CfpwFCjPUIs/A==", + "dev": true, + "requires": { + "regex-utilities": "^2.3.0" + } + }, + "regex-utilities": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/regex-utilities/-/regex-utilities-2.3.0.tgz", + "integrity": "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==", "dev": true }, "request-progress": { @@ -15512,27 +15062,30 @@ "dev": true }, "rollup": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.0.tgz", - "integrity": "sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==", - "dev": true, - "requires": { - "@rollup/rollup-android-arm-eabi": "4.24.0", - "@rollup/rollup-android-arm64": "4.24.0", - "@rollup/rollup-darwin-arm64": "4.24.0", - "@rollup/rollup-darwin-x64": "4.24.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.24.0", - "@rollup/rollup-linux-arm-musleabihf": "4.24.0", - "@rollup/rollup-linux-arm64-gnu": "4.24.0", - "@rollup/rollup-linux-arm64-musl": "4.24.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.24.0", - "@rollup/rollup-linux-riscv64-gnu": "4.24.0", - "@rollup/rollup-linux-s390x-gnu": "4.24.0", - "@rollup/rollup-linux-x64-gnu": "4.24.0", - "@rollup/rollup-linux-x64-musl": "4.24.0", - "@rollup/rollup-win32-arm64-msvc": "4.24.0", - "@rollup/rollup-win32-ia32-msvc": "4.24.0", - "@rollup/rollup-win32-x64-msvc": "4.24.0", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.28.1.tgz", + "integrity": "sha512-61fXYl/qNVinKmGSTHAZ6Yy8I3YIJC/r2m9feHo6SwVAVcLT5MPwOUFe7EuURA/4m0NR8lXG4BBXuo/IZEsjMg==", + "dev": true, + "requires": { + "@rollup/rollup-android-arm-eabi": "4.28.1", + "@rollup/rollup-android-arm64": "4.28.1", + "@rollup/rollup-darwin-arm64": "4.28.1", + "@rollup/rollup-darwin-x64": "4.28.1", + "@rollup/rollup-freebsd-arm64": "4.28.1", + "@rollup/rollup-freebsd-x64": "4.28.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.28.1", + "@rollup/rollup-linux-arm-musleabihf": "4.28.1", + "@rollup/rollup-linux-arm64-gnu": "4.28.1", + "@rollup/rollup-linux-arm64-musl": "4.28.1", + "@rollup/rollup-linux-loongarch64-gnu": "4.28.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.28.1", + "@rollup/rollup-linux-riscv64-gnu": "4.28.1", + "@rollup/rollup-linux-s390x-gnu": "4.28.1", + "@rollup/rollup-linux-x64-gnu": "4.28.1", + "@rollup/rollup-linux-x64-musl": "4.28.1", + "@rollup/rollup-win32-arm64-msvc": "4.28.1", + "@rollup/rollup-win32-ia32-msvc": "4.28.1", + "@rollup/rollup-win32-x64-msvc": "4.28.1", "@types/estree": "1.0.6", "fsevents": "~2.3.2" } @@ -15586,16 +15139,16 @@ "dev": true }, "sass": { - "version": "1.80.3", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.80.3.tgz", - "integrity": "sha512-ptDWyVmDMVielpz/oWy3YP3nfs7LpJTHIJZboMVs8GEC9eUmtZTZhMHlTW98wY4aEorDfjN38+Wr/XjskFWcfA==", + "version": "1.83.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.83.0.tgz", + "integrity": "sha512-qsSxlayzoOjdvXMVLkzF84DJFc2HZEL/rFyGIKbbilYtAvlCxyuzUeff9LawTn4btVnLKg75Z8MMr1lxU1lfGw==", "dev": true, "optional": true, "peer": true, "requires": { "@parcel/watcher": "^2.4.1", "chokidar": "^4.0.0", - "immutable": "^4.0.0", + "immutable": "^5.0.2", "source-map-js": ">=0.6.2 <2.0.0" }, "dependencies": { @@ -15678,15 +15231,15 @@ "dev": true }, "shiki": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.22.0.tgz", - "integrity": "sha512-/t5LlhNs+UOKQCYBtl5ZsH/Vclz73GIqT2yQsCBygr8L/ppTdmpL4w3kPLoZJbMKVWtoG77Ue1feOjZfDxvMkw==", + "version": "1.24.2", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.24.2.tgz", + "integrity": "sha512-TR1fi6mkRrzW+SKT5G6uKuc32Dj2EEa7Kj0k8kGqiBINb+C1TiflVOiT9ta6GqOJtC4fraxO5SLUaKBcSY38Fg==", "dev": true, "requires": { - "@shikijs/core": "1.22.0", - "@shikijs/engine-javascript": "1.22.0", - "@shikijs/engine-oniguruma": "1.22.0", - "@shikijs/types": "1.22.0", + "@shikijs/core": "1.24.2", + "@shikijs/engine-javascript": "1.24.2", + "@shikijs/engine-oniguruma": "1.24.2", + "@shikijs/types": "1.24.2", "@shikijs/vscode-textmate": "^9.3.0", "@types/hast": "^3.0.4" } @@ -15746,32 +15299,12 @@ "is-fullwidth-code-point": "^3.0.0" } }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "optional": true, - "peer": true - }, "source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true }, - "source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, "space-separated-tokens": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", @@ -15927,9 +15460,9 @@ "dev": true }, "superjson": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.1.tgz", - "integrity": "sha512-8iGv75BYOa0xRJHK5vRLEjE2H/i4lulTjzpUXic3Eg8akftYjkmQDa8JARQ42rlczXyFR3IeRoeFCc7RxHsYZA==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.2.tgz", + "integrity": "sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==", "dev": true, "requires": { "copy-anything": "^3.0.2" @@ -15944,30 +15477,6 @@ "has-flag": "^4.0.0" } }, - "terser": { - "version": "5.31.6", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.6.tgz", - "integrity": "sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true, - "optional": true, - "peer": true - } - } - }, "throttleit": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.1.tgz", @@ -16214,15 +15723,210 @@ } }, "vite": { - "version": "5.4.8", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.8.tgz", - "integrity": "sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.0.3.tgz", + "integrity": "sha512-Cmuo5P0ENTN6HxLSo6IHsjCLn/81Vgrp81oaiFFMRa8gGDj5xEjIcEpf2ZymZtZR8oU0P2JX5WuUp/rlXcHkAw==", "dev": true, "requires": { - "esbuild": "^0.21.3", + "esbuild": "^0.24.0", "fsevents": "~2.3.3", - "postcss": "^8.4.43", - "rollup": "^4.20.0" + "postcss": "^8.4.49", + "rollup": "^4.23.0" + }, + "dependencies": { + "@esbuild/aix-ppc64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.0.tgz", + "integrity": "sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.0.tgz", + "integrity": "sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.0.tgz", + "integrity": "sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==", + "dev": true, + "optional": true + }, + "@esbuild/android-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.0.tgz", + "integrity": "sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.0.tgz", + "integrity": "sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.0.tgz", + "integrity": "sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.0.tgz", + "integrity": "sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.0.tgz", + "integrity": "sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.0.tgz", + "integrity": "sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.0.tgz", + "integrity": "sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ia32": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.0.tgz", + "integrity": "sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.0.tgz", + "integrity": "sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==", + "dev": true, + "optional": true + }, + "@esbuild/linux-mips64el": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.0.tgz", + "integrity": "sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ppc64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.0.tgz", + "integrity": "sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-riscv64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.0.tgz", + "integrity": "sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==", + "dev": true, + "optional": true + }, + "@esbuild/linux-s390x": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.0.tgz", + "integrity": "sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==", + "dev": true, + "optional": true + }, + "@esbuild/linux-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.0.tgz", + "integrity": "sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==", + "dev": true, + "optional": true + }, + "@esbuild/netbsd-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.0.tgz", + "integrity": "sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==", + "dev": true, + "optional": true + }, + "@esbuild/openbsd-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.0.tgz", + "integrity": "sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==", + "dev": true, + "optional": true + }, + "@esbuild/sunos-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.0.tgz", + "integrity": "sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==", + "dev": true, + "optional": true + }, + "@esbuild/win32-arm64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.0.tgz", + "integrity": "sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==", + "dev": true, + "optional": true + }, + "@esbuild/win32-ia32": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.0.tgz", + "integrity": "sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==", + "dev": true, + "optional": true + }, + "@esbuild/win32-x64": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.0.tgz", + "integrity": "sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==", + "dev": true, + "optional": true + }, + "esbuild": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.0.tgz", + "integrity": "sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==", + "dev": true, + "requires": { + "@esbuild/aix-ppc64": "0.24.0", + "@esbuild/android-arm": "0.24.0", + "@esbuild/android-arm64": "0.24.0", + "@esbuild/android-x64": "0.24.0", + "@esbuild/darwin-arm64": "0.24.0", + "@esbuild/darwin-x64": "0.24.0", + "@esbuild/freebsd-arm64": "0.24.0", + "@esbuild/freebsd-x64": "0.24.0", + "@esbuild/linux-arm": "0.24.0", + "@esbuild/linux-arm64": "0.24.0", + "@esbuild/linux-ia32": "0.24.0", + "@esbuild/linux-loong64": "0.24.0", + "@esbuild/linux-mips64el": "0.24.0", + "@esbuild/linux-ppc64": "0.24.0", + "@esbuild/linux-riscv64": "0.24.0", + "@esbuild/linux-s390x": "0.24.0", + "@esbuild/linux-x64": "0.24.0", + "@esbuild/netbsd-x64": "0.24.0", + "@esbuild/openbsd-arm64": "0.24.0", + "@esbuild/openbsd-x64": "0.24.0", + "@esbuild/sunos-x64": "0.24.0", + "@esbuild/win32-arm64": "0.24.0", + "@esbuild/win32-ia32": "0.24.0", + "@esbuild/win32-x64": "0.24.0" + } + } } }, "vscode-jsonrpc": { @@ -16282,75 +15986,64 @@ } }, "vue-router": { - "version": "4.4.5", - "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.4.5.tgz", - "integrity": "sha512-4fKZygS8cH1yCyuabAXGUAsyi1b2/o/OKgu/RUb+znIYOxPRxdkytJEx+0wGcpBE1pX6vUgh5jwWOKRGvuA/7Q==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.5.0.tgz", + "integrity": "sha512-HDuk+PuH5monfNuY+ct49mNmkCRK4xJAV9Ts4z9UFc4rzdDnxQLyCMGGc8pKhZhHTVzfanpNwB/lwqevcBwI4w==", "dev": true, "requires": { "@vue/devtools-api": "^6.6.4" } }, "vuepress": { - "version": "2.0.0-rc.18", - "resolved": "https://registry.npmjs.org/vuepress/-/vuepress-2.0.0-rc.18.tgz", - "integrity": "sha512-TFpePHTIMiUbiJcHTgD4Wc5eBlsxBnhv36F/eM2vbDoeutcS1dGrNtZoKUxrZDXTeZH+q8vrZ3CiBCsHw3K7eA==", + "version": "2.0.0-rc.19", + "resolved": "https://registry.npmjs.org/vuepress/-/vuepress-2.0.0-rc.19.tgz", + "integrity": "sha512-JDeuPTu14Kprdqx2geAryjFJvUzVaMnOLewlAgwVuZTygDWb8cgXhu9/p6rqzzdHETtIrvjbASBhH7JPyqmxmA==", "dev": true, "requires": { - "@vuepress/cli": "2.0.0-rc.18", - "@vuepress/client": "2.0.0-rc.18", - "@vuepress/core": "2.0.0-rc.18", - "@vuepress/markdown": "2.0.0-rc.18", - "@vuepress/shared": "2.0.0-rc.18", - "@vuepress/utils": "2.0.0-rc.18", - "vue": "^3.5.11" + "@vuepress/cli": "2.0.0-rc.19", + "@vuepress/client": "2.0.0-rc.19", + "@vuepress/core": "2.0.0-rc.19", + "@vuepress/markdown": "2.0.0-rc.19", + "@vuepress/shared": "2.0.0-rc.19", + "@vuepress/utils": "2.0.0-rc.19", + "vue": "^3.5.13" } }, "vuepress-plugin-components": { - "version": "2.0.0-rc.59", - "resolved": "https://registry.npmjs.org/vuepress-plugin-components/-/vuepress-plugin-components-2.0.0-rc.59.tgz", - "integrity": "sha512-LRA4uHW+a6D3wZkElMRmafeFhUXwwkVccWoSSnuTfI70mdqOnuaiPLQIQ0akyLBx41npervol6MRi8brqbjliw==", + "version": "2.0.0-rc.64", + "resolved": "https://registry.npmjs.org/vuepress-plugin-components/-/vuepress-plugin-components-2.0.0-rc.64.tgz", + "integrity": "sha512-rRfm6YfieQoKmfqZYlM+S5N7sU+iiwlAb80uEo+CTMm7lxsPSDRH2X13u3op35KQn/QWqkEVkf75vTesyBZZhw==", "dev": true, "requires": { "@stackblitz/sdk": "^1.11.0", - "@vuepress/helper": "2.0.0-rc.56", - "@vuepress/plugin-sass-palette": "2.0.0-rc.56", - "@vueuse/core": "^11.1.0", + "@vuepress/helper": "2.0.0-rc.66", + "@vuepress/plugin-sass-palette": "2.0.0-rc.66", + "@vueuse/core": "^12.0.0", "balloon-css": "^1.2.0", "create-codepen": "^2.0.0", "qrcode": "^1.5.4", - "vue": "^3.5.12", - "vuepress-shared": "2.0.0-rc.59" + "vue": "^3.5.13", + "vuepress-shared": "2.0.0-rc.64" } }, "vuepress-plugin-md-enhance": { - "version": "2.0.0-rc.59", - "resolved": "https://registry.npmjs.org/vuepress-plugin-md-enhance/-/vuepress-plugin-md-enhance-2.0.0-rc.59.tgz", - "integrity": "sha512-XFf6OG5arp1bJHP3gUDibKcoYaWLdZvU6xXypIMXa+Q5f2I51l9zd6vuLw58DcHWQyhNUTdtDE6srohUtOxQ/A==", - "dev": true, - "requires": { - "@mdit/plugin-alert": "^0.13.1", - "@mdit/plugin-align": "^0.13.1", - "@mdit/plugin-attrs": "^0.13.1", - "@mdit/plugin-container": "^0.13.1", - "@mdit/plugin-demo": "^0.13.1", - "@mdit/plugin-footnote": "^0.13.1", - "@mdit/plugin-include": "^0.13.1", - "@mdit/plugin-mark": "^0.13.1", - "@mdit/plugin-plantuml": "^0.13.1", - "@mdit/plugin-spoiler": "^0.13.1", - "@mdit/plugin-stylize": "^0.13.1", - "@mdit/plugin-sub": "^0.13.1", - "@mdit/plugin-sup": "^0.13.1", - "@mdit/plugin-tasklist": "^0.13.1", - "@mdit/plugin-uml": "^0.13.1", + "version": "2.0.0-rc.64", + "resolved": "https://registry.npmjs.org/vuepress-plugin-md-enhance/-/vuepress-plugin-md-enhance-2.0.0-rc.64.tgz", + "integrity": "sha512-pwXEDaUXyo1tfcA4n4l3Ql0aTBwju+eNO+5wL9TwtsCgCTsAo63pQIrv/XRwFuHJRHKj3HfrlEcNuDn2uxPH+A==", + "dev": true, + "requires": { + "@mdit/plugin-container": "^0.14.0", + "@mdit/plugin-demo": "^0.14.0", + "@mdit/plugin-plantuml": "^0.14.0", + "@mdit/plugin-uml": "^0.14.0", "@types/markdown-it": "^14.1.2", - "@vuepress/helper": "2.0.0-rc.56", - "@vuepress/plugin-sass-palette": "2.0.0-rc.56", - "@vueuse/core": "^11.1.0", + "@vuepress/helper": "2.0.0-rc.66", + "@vuepress/plugin-sass-palette": "2.0.0-rc.66", + "@vueuse/core": "^12.0.0", "balloon-css": "^1.2.0", "js-yaml": "^4.1.0", - "vue": "^3.5.12", - "vuepress-shared": "2.0.0-rc.59" + "vue": "^3.5.13", + "vuepress-shared": "2.0.0-rc.64" }, "dependencies": { "argparse": { @@ -16371,86 +16064,60 @@ } }, "vuepress-shared": { - "version": "2.0.0-rc.59", - "resolved": "https://registry.npmjs.org/vuepress-shared/-/vuepress-shared-2.0.0-rc.59.tgz", - "integrity": "sha512-NUGEX8e4TQ2L6F7ooLDELRtUWiHxE5ztP1rJxyg9FzKZ6MiINB5b669LcQSh/xAlY4fm9p80Y4C/52+zmNDEoA==", + "version": "2.0.0-rc.64", + "resolved": "https://registry.npmjs.org/vuepress-shared/-/vuepress-shared-2.0.0-rc.64.tgz", + "integrity": "sha512-YA0z7Pwob8Bj7uHNHBXGpH6GeaLAhBFlvBtTM136zZhsUb2mQptB67y1B03RLDYtfzMP06WKCh449azdVbZykA==", "dev": true, "requires": { - "@vuepress/helper": "2.0.0-rc.56", - "@vueuse/core": "^11.1.0", + "@vuepress/helper": "2.0.0-rc.66", + "@vueuse/core": "^12.0.0", "dayjs": "^1.11.13", - "vue": "^3.5.12" + "vue": "^3.5.13" } }, "vuepress-theme-hope": { - "version": "2.0.0-rc.59", - "resolved": "https://registry.npmjs.org/vuepress-theme-hope/-/vuepress-theme-hope-2.0.0-rc.59.tgz", - "integrity": "sha512-o+5P+xMy0y2HPWb3bmVE2AMWbMCdsdDfET6APWqXm6ccyhXW7cDStwho5cuwQmVasqSZSYS950dAahEcsj0wlg==", - "dev": true, - "requires": { - "@vuepress/helper": "2.0.0-rc.56", - "@vuepress/plugin-active-header-links": "2.0.0-rc.55", - "@vuepress/plugin-back-to-top": "2.0.0-rc.56", - "@vuepress/plugin-blog": "2.0.0-rc.56", - "@vuepress/plugin-catalog": "2.0.0-rc.56", - "@vuepress/plugin-comment": "2.0.0-rc.56", - "@vuepress/plugin-copy-code": "2.0.0-rc.56", - "@vuepress/plugin-copyright": "2.0.0-rc.56", - "@vuepress/plugin-git": "2.0.0-rc.54", - "@vuepress/plugin-links-check": "2.0.0-rc.56", - "@vuepress/plugin-markdown-hint": "2.0.0-rc.56", - "@vuepress/plugin-markdown-image": "2.0.0-rc.56", - "@vuepress/plugin-markdown-math": "2.0.0-rc.56", - "@vuepress/plugin-markdown-tab": "2.0.0-rc.56", - "@vuepress/plugin-notice": "2.0.0-rc.56", - "@vuepress/plugin-nprogress": "2.0.0-rc.56", - "@vuepress/plugin-photo-swipe": "2.0.0-rc.56", - "@vuepress/plugin-reading-time": "2.0.0-rc.56", - "@vuepress/plugin-redirect": "2.0.0-rc.56", - "@vuepress/plugin-rtl": "2.0.0-rc.56", - "@vuepress/plugin-sass-palette": "2.0.0-rc.56", - "@vuepress/plugin-seo": "2.0.0-rc.56", - "@vuepress/plugin-shiki": "2.0.0-rc.56", - "@vuepress/plugin-sitemap": "2.0.0-rc.56", - "@vuepress/plugin-theme-data": "2.0.0-rc.56", - "@vuepress/plugin-watermark": "2.0.0-rc.56", - "@vueuse/core": "^11.1.0", + "version": "2.0.0-rc.64", + "resolved": "https://registry.npmjs.org/vuepress-theme-hope/-/vuepress-theme-hope-2.0.0-rc.64.tgz", + "integrity": "sha512-nRy00CHINQXeKa7ztOyRyYPnP0rzL2iyEDTXMGOEbBtYS2RCp6CM/587nCKV7VXrFPY/3Ps/4C2Abf9kTkMdwA==", + "dev": true, + "requires": { + "@vuepress/helper": "2.0.0-rc.66", + "@vuepress/plugin-active-header-links": "2.0.0-rc.66", + "@vuepress/plugin-back-to-top": "2.0.0-rc.66", + "@vuepress/plugin-blog": "2.0.0-rc.66", + "@vuepress/plugin-catalog": "2.0.0-rc.66", + "@vuepress/plugin-comment": "2.0.0-rc.66", + "@vuepress/plugin-copy-code": "2.0.0-rc.66", + "@vuepress/plugin-copyright": "2.0.0-rc.66", + "@vuepress/plugin-git": "2.0.0-rc.66", + "@vuepress/plugin-links-check": "2.0.0-rc.66", + "@vuepress/plugin-markdown-ext": "2.0.0-rc.66", + "@vuepress/plugin-markdown-hint": "2.0.0-rc.66", + "@vuepress/plugin-markdown-image": "2.0.0-rc.66", + "@vuepress/plugin-markdown-include": "2.0.0-rc.66", + "@vuepress/plugin-markdown-math": "2.0.0-rc.66", + "@vuepress/plugin-markdown-stylize": "2.0.0-rc.66", + "@vuepress/plugin-markdown-tab": "2.0.0-rc.66", + "@vuepress/plugin-notice": "2.0.0-rc.66", + "@vuepress/plugin-nprogress": "2.0.0-rc.66", + "@vuepress/plugin-photo-swipe": "2.0.0-rc.66", + "@vuepress/plugin-reading-time": "2.0.0-rc.66", + "@vuepress/plugin-redirect": "2.0.0-rc.66", + "@vuepress/plugin-rtl": "2.0.0-rc.66", + "@vuepress/plugin-sass-palette": "2.0.0-rc.66", + "@vuepress/plugin-seo": "2.0.0-rc.66", + "@vuepress/plugin-shiki": "2.0.0-rc.66", + "@vuepress/plugin-sitemap": "2.0.0-rc.66", + "@vuepress/plugin-theme-data": "2.0.0-rc.66", + "@vuepress/plugin-watermark": "2.0.0-rc.66", + "@vueuse/core": "^12.0.0", "balloon-css": "^1.2.0", - "bcrypt-ts": "^5.0.2", + "bcrypt-ts": "^5.0.3", "chokidar": "^3.6.0", - "vue": "^3.5.12", - "vuepress-plugin-components": "2.0.0-rc.59", - "vuepress-plugin-md-enhance": "2.0.0-rc.59", - "vuepress-shared": "2.0.0-rc.59" - }, - "dependencies": { - "@vuepress/plugin-markdown-image": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-markdown-image/-/plugin-markdown-image-2.0.0-rc.56.tgz", - "integrity": "sha512-oIqVz1rvUfteIQhESZNuTgeLU9neLVrdC041e+yRakJShAGKXVPJoZE09wjQoHZM0RE2Qkd+EkAYQGB7fKFgbw==", - "dev": true, - "requires": { - "@mdit/plugin-figure": "^0.13.1", - "@mdit/plugin-img-lazyload": "^0.13.1", - "@mdit/plugin-img-mark": "^0.13.1", - "@mdit/plugin-img-size": "^0.13.1", - "@types/markdown-it": "^14.1.2", - "@vuepress/helper": "2.0.0-rc.56" - } - }, - "@vuepress/plugin-markdown-tab": { - "version": "2.0.0-rc.56", - "resolved": "https://registry.npmjs.org/@vuepress/plugin-markdown-tab/-/plugin-markdown-tab-2.0.0-rc.56.tgz", - "integrity": "sha512-qqL+mlGuccnyJg7rdOBXJg5UEppMxObQZfhnuoiuu4BE8C0kV7G/myMOWsHLH0My8zpXdl5beKJqOdrjZapJqg==", - "dev": true, - "requires": { - "@mdit/plugin-tab": "^0.13.2", - "@types/markdown-it": "^14.1.2", - "@vuepress/helper": "2.0.0-rc.56", - "@vueuse/core": "^11.1.0", - "vue": "^3.5.12" - } - } + "vue": "^3.5.13", + "vuepress-plugin-components": "2.0.0-rc.64", + "vuepress-plugin-md-enhance": "2.0.0-rc.64", + "vuepress-shared": "2.0.0-rc.64" } }, "wait-on": { diff --git a/package.json b/package.json index 580e5c1f6..ee24e4db6 100644 --- a/package.json +++ b/package.json @@ -15,16 +15,16 @@ "cy:run": "cypress run --e2e" }, "devDependencies": { - "@vuepress/bundler-vite": "2.0.0-rc.18", - "@vuepress/plugin-markdown-image": "2.0.0-rc.62", - "@vuepress/plugin-markdown-tab": "2.0.0-rc.62", + "@vuepress/bundler-vite": "2.0.0-rc.19", + "@vuepress/plugin-markdown-image": "2.0.0-rc.66", + "@vuepress/plugin-markdown-tab": "2.0.0-rc.66", "cypress": "^13.16.1", "cypress-each": "^1.14.0", "flowchart.ts": "^3.0.1", "mermaid": "^11.4.1", "start-server-and-test": "^2.0.9", "vue": "^3.5.13", - "vuepress": "2.0.0-rc.18", - "vuepress-theme-hope": "2.0.0-rc.59" + "vuepress": "2.0.0-rc.19", + "vuepress-theme-hope": "2.0.0-rc.64" } }