diff --git a/.github/workflows/README.md b/.github/workflows/README.md new file mode 100644 index 0000000..3c9b262 --- /dev/null +++ b/.github/workflows/README.md @@ -0,0 +1,343 @@ +# HypnoScript Rust CI/CD Pipelines + +This directory contains GitHub Actions workflows for building, testing, and deploying the Rust-based HypnoScript implementation. + +## Workflows + +### 1. `rust-build-and-test.yml` - Main CI Pipeline + +**Triggers:** + +- Push to `main` or `develop` branches +- Pull requests to `main` or `develop` + +**Jobs:** + +#### `build-and-test` + +- **Platforms:** Windows, Linux, macOS +- **Rust Version:** Stable +- **Steps:** + - Code formatting check (`cargo fmt`) + - Linting with Clippy (`cargo clippy`) + - Build all workspace crates + - Run all unit and integration tests + - Test CLI functionality (lex, parse, check, run) + - Upload binaries as artifacts + +#### `code-quality` + +- **Platform:** Ubuntu +- **Steps:** + - CodeQL security analysis (Rust) + - Cargo audit for vulnerability scanning + - Check for unsafe code blocks + - Cargo deny for license and security checks + +#### `performance` + +- **Platform:** Ubuntu +- **Steps:** + - Run benchmark tests + - Generate performance reports + - Time execution of sample programs + +#### `coverage` + +- **Platform:** Ubuntu +- **Steps:** + - Generate code coverage with `cargo-llvm-cov` + - Upload to Codecov + +#### `deployment` + +- **Platform:** Ubuntu +- **Triggers:** Only on `main` branch +- **Steps:** + - Build release binaries + - Create release package (tar.gz) + - Upload artifacts + +--- + +### 2. `rust-build-and-release.yml` - Release Pipeline + +**Triggers:** + +- Tags matching `v*.*.*` or `rust-v*.*.*` + +**Jobs:** + +#### `build-release` + +- **Strategy:** Matrix build for multiple platforms +- **Targets:** + - Linux x64 (glibc) + - Linux x64 (musl - static) + - Windows x64 + - macOS x64 + - macOS ARM64 +- **Steps:** + - Cross-compile for target platform + - Strip binaries (Unix only) + - Create platform-specific archives + - Compute SHA256 checksums + +#### `build-deb-package` + +- **Platform:** Ubuntu +- **Steps:** + - Build Debian package with `cargo-deb` + - Package for APT repositories + +#### `create-release` + +- **Depends:** build-release, build-deb-package +- **Steps:** + - Download all platform artifacts + - Create GitHub Release + - Upload all binaries and checksums + - Include installation instructions + +#### `publish-crates` + +- **Triggers:** Only on version tags +- **Steps:** + - Publish all crates to crates.io + - Sequential publishing with delays + +--- + +### 3. `deploy-docs.yml` - Documentation Pipeline + +**Triggers:** + +- Push to `main` affecting documentation or Rust code +- Pull requests affecting documentation + +**Jobs:** + +#### `build-and-deploy` + +- **Platform:** Ubuntu +- **Steps:** + - Build Rust API documentation (`cargo doc`) + - Build user documentation (npm) + - Combine both documentation sources + - Deploy to GitHub Pages (main branch only) + +#### `test-build` + +- **Platform:** Ubuntu +- **Triggers:** Pull requests only +- **Steps:** + - Build Rust documentation + - Build user documentation + - Check for broken links + +--- + +## Required Secrets + +For full functionality, configure these GitHub repository secrets: + +- `CARGO_TOKEN` - Token for publishing to crates.io (optional) +- `GITHUB_TOKEN` - Automatically provided by GitHub Actions + +## Caching Strategy + +All workflows use caching to speed up builds: + +- **Cargo registry** - Downloaded dependencies +- **Cargo git** - Git dependencies +- **Cargo build** - Compiled artifacts +- **NPM packages** - Node.js dependencies + +## Testing Strategy + +### Unit Tests + +```bash +cargo test --workspace +``` + +### Integration Tests + +```bash +cargo test --package hypnoscript-lexer-parser +cargo test --package hypnoscript-compiler +cargo test --package hypnoscript-runtime +``` + +### CLI Tests + +```bash +hypnoscript-cli version +hypnoscript-cli builtins +hypnoscript-cli lex +hypnoscript-cli parse +hypnoscript-cli check +hypnoscript-cli run +``` + +### Performance Tests + +```bash +cargo test --release -- --ignored --nocapture +``` + +## Code Quality Checks + +### Formatting + +```bash +cargo fmt --all -- --check +``` + +### Linting + +```bash +cargo clippy --all-targets --all-features -- -D warnings +``` + +### Security Audit + +```bash +cargo audit +``` + +### Coverage + +```bash +cargo llvm-cov --all-features --workspace +``` + +## Release Process + +1. **Update version** in all `Cargo.toml` files +2. **Create tag:** + + ```bash + git tag -a v1.0.0 -m "Release v1.0.0" + git push origin v1.0.0 + ``` + +3. **GitHub Actions automatically:** + - Builds binaries for all platforms + - Creates Debian package + - Generates checksums + - Creates GitHub Release + - Publishes to crates.io (optional) + +## Platform-Specific Notes + +### Linux (glibc) + +- Target: `x86_64-unknown-linux-gnu` +- Requires glibc 2.17+ +- Most compatible with modern Linux distributions + +### Linux (musl) + +- Target: `x86_64-unknown-linux-musl` +- Static binary, no runtime dependencies +- Ideal for containers and embedded systems + +### Windows + +- Target: `x86_64-pc-windows-msvc` +- Requires Visual C++ runtime (usually pre-installed) + +### macOS x64 + +- Target: `x86_64-apple-darwin` +- Intel-based Macs + +### macOS ARM64 + +- Target: `aarch64-apple-darwin` +- Apple Silicon (M1/M2/M3) Macs + +## Continuous Deployment + +The `deployment` job on the main branch automatically: + +1. Builds release binaries +2. Creates a release package +3. Uploads to GitHub Artifacts + +For tagged releases, the full release workflow: + +1. Builds for all platforms +2. Creates GitHub Release +3. Publishes to crates.io + +## Monitoring + +- **Test Results:** Available in Actions artifacts +- **Code Coverage:** Uploaded to Codecov +- **Security:** CodeQL alerts in Security tab +- **Performance:** Benchmark results in artifacts + +## Development Workflow + +1. **Create feature branch** +2. **Make changes** to Rust code +3. **Run local tests:** + + ```bash + cargo test + cargo clippy + cargo fmt + ``` + +4. **Push to branch** - triggers CI +5. **Create PR** - full test suite runs +6. **Merge to main** - triggers deployment +7. **Tag release** - triggers multi-platform build + +## Migration from C# Pipelines + +The Rust pipelines replace the C# pipelines with equivalent functionality: + +| C# Pipeline | Rust Pipeline | Notes | +| ----------------------- | ---------------------------- | --------------------------- | +| `build-and-test.yml` | `rust-build-and-test.yml` | Same structure, Rust tools | +| `build-and-release.yml` | `rust-build-and-release.yml` | Multi-platform support | +| `deploy-docs.yml` | `deploy-docs.yml` | Enhanced with Rust API docs | + +## Performance Comparison + +Rust CI is generally faster than C#: + +- **Build time:** ~2-5 minutes (vs 5-10 for C#) +- **Test time:** ~1-2 minutes (vs 3-5 for C#) +- **Binary size:** 5-10MB (vs 60+MB for C#) +- **Cache efficiency:** Better with incremental compilation + +## Troubleshooting + +### Build Failures + +- Check Rust version compatibility +- Verify Cargo.lock is committed +- Review clippy warnings + +### Test Failures + +- Run tests locally first +- Check for platform-specific issues +- Review test output in artifacts + +### Release Issues + +- Ensure all Cargo.toml versions match +- Check tag format (v*.*.\*) +- Verify CARGO_TOKEN is set for crates.io + +## Further Reading + +- [GitHub Actions Documentation](https://docs.github.com/en/actions) +- [Rust CI/CD Best Practices](https://doc.rust-lang.org/cargo/guide/continuous-integration.html) +- [cargo-deb Documentation](https://github.com/kornelski/cargo-deb) +- [Cross-compilation Guide](https://rust-lang.github.io/rustup/cross-compilation.html) diff --git a/.github/workflows/build-and-release.yml b/.github/workflows/build-and-release.yml deleted file mode 100644 index 7bb2990..0000000 --- a/.github/workflows/build-and-release.yml +++ /dev/null @@ -1,66 +0,0 @@ -name: Build & Release HypnoScript - -on: - push: - tags: - - 'v*.*.*' - -jobs: - build-release: - runs-on: ubuntu-latest - env: - DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 - DOTNET_CLI_TELEMETRY_OPTOUT: 1 - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Setup .NET - uses: actions/setup-dotnet@v4 - with: - dotnet-version: '8.0.x' - - - name: Install fpm (for .deb build) - run: | - sudo apt-get update - sudo apt-get install -y ruby ruby-dev build-essential - sudo gem install --no-document fpm - - - name: Build Windows ZIP (winget) - shell: pwsh - run: | - mkdir -Force publish - pwsh scripts/build_winget.ps1 - - - name: Build Linux .deb (APT) - run: | - mkdir -p publish - bash scripts/build_deb.sh - - - name: Compute SHA256 for Windows ZIP - id: sha256 - run: | - sha256sum publish/HypnoScript-windows-x64.zip | awk '{print $1}' > publish/sha256.txt - echo "sha256=$(cat publish/sha256.txt)" >> $GITHUB_OUTPUT - - - name: Generate Builtins Documentation - run: | - dotnet run --project HypnoScript.Runtime/Builtins/DocGenerator.cs HypnoScript.Dokumentation/docs/builtins/ - - - name: Create Release - uses: softprops/action-gh-release@v1 - with: - files: | - publish/HypnoScript-windows-x64.zip - publish/hypnoscript_1.0.0_amd64.deb - publish/sha256.txt - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Print SHA256 for winget manifest - run: | - echo "SHA256 for winget-manifest.yaml: ${{ steps.sha256.outputs.sha256 }}" - - - name: Hinweis für winget-Update - run: | - echo 'Bitte SHA256 in scripts/winget-manifest.yaml aktualisieren und PR an winget-pkgs stellen.' diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml deleted file mode 100644 index ca31e28..0000000 --- a/.github/workflows/build-and-test.yml +++ /dev/null @@ -1,186 +0,0 @@ -name: Build and Test - -on: - push: - branches: [main, develop] - pull_request: - branches: [main, develop] - -jobs: - build-and-test: - runs-on: ${{ matrix.os }} - - strategy: - matrix: - os: [windows-latest, ubuntu-latest] - dotnet-version: ['8.0.x'] - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup .NET - uses: actions/setup-dotnet@v4 - with: - dotnet-version: ${{ matrix.dotnet-version }} - - - name: Restore dependencies - run: dotnet restore HypnoScript.sln - - - name: Build - run: dotnet build HypnoScript.sln --no-restore --configuration Release - - - name: Test - run: dotnet test HypnoScript.sln --no-build --verbosity normal --configuration Release - - - name: Run integration tests - run: | - dotnet test HypnoScript.CLI.Tests --no-build --verbosity normal --configuration Release - dotnet test HypnoScript.Compiler.Tests --no-build --verbosity normal --configuration Release - dotnet test HypnoScript.Runtime.Tests --no-build --verbosity normal --configuration Release - - - name: Upload test results - uses: actions/upload-artifact@v4 - if: always() - with: - name: test-results-${{ matrix.os }} - path: | - **/TestResults/ - **/test-results.xml - - - name: Build documentation - working-directory: HypnoScript.Dokumentation - run: | - npm install - npm run build - - - name: Upload documentation - uses: actions/upload-artifact@v4 - with: - name: documentation-${{ matrix.os }} - path: HypnoScript.Dokumentation/build/ - - code-quality: - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup .NET - uses: actions/setup-dotnet@v4 - with: - dotnet-version: '8.0.x' - - - name: Install CodeQL - uses: github/codeql-action/init@v3 - with: - languages: csharp - - - name: Build for CodeQL - run: dotnet build HypnoScript.sln --configuration Release - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 - - - name: Run security scan - run: | - dotnet tool install --global dotnet-format - dotnet format HypnoScript.sln --verify-no-changes - - - name: Check for TODO comments - run: | - if grep -r "TODO\|FIXME\|HACK" --include="*.cs" .; then - echo "Found TODO/FIXME/HACK comments in code" - exit 1 - fi - - performance: - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup .NET - uses: actions/setup-dotnet@v4 - with: - dotnet-version: '8.0.x' - - - name: Build - run: dotnet build HypnoScript.sln --configuration Release - - - name: Run performance tests - run: | - dotnet test HypnoScript.sln --filter "Category=Performance" --configuration Release --logger "console;verbosity=detailed" - - - name: Generate performance report - run: | - dotnet run --project HypnoScript.CLI -- benchmark test_basic.hyp --verbose - dotnet run --project HypnoScript.CLI -- profile test_basic.hyp --verbose - - - name: Upload performance results - uses: actions/upload-artifact@v4 - with: - name: performance-results - path: | - **/benchmark-results/ - **/profile-results/ - - deployment: - needs: [build-and-test, code-quality, performance] - runs-on: ubuntu-latest - if: github.ref == 'refs/heads/main' - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup .NET - uses: actions/setup-dotnet@v4 - with: - dotnet-version: '8.0.x' - - - name: Build for release - run: dotnet build HypnoScript.sln --configuration Release --output ./publish - - - name: Create release package - run: | - mkdir -p release - cp -r publish/* release/ - cp README.md release/ - cp LICENSE release/ - tar -czf hypnoscript-release.tar.gz -C release . - - - name: Upload release artifacts - uses: actions/upload-artifact@v4 - with: - name: release-package - path: hypnoscript-release.tar.gz - - - name: Create GitHub Release - uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: v${{ github.run_number }} - release_name: Release v${{ github.run_number }} - body: | - Automated release from CI/CD pipeline - - Changes: - - Build and test automation - - Code quality improvements - - Performance optimizations - draft: false - prerelease: false - - - name: Upload to GitHub Release - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: ./hypnoscript-release.tar.gz - asset_name: hypnoscript-v${{ github.run_number }}.tar.gz - asset_content_type: application/gzip diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index ff95870..29f6d48 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -1,76 +1,155 @@ -name: Deploy Documentation to GitHub Pages +name: Deploy VitePress Documentation to GitHub Pages permissions: - contents: write + contents: read + pages: write + id-token: write + +# Allow one concurrent deployment +concurrency: + group: pages + cancel-in-progress: false on: push: branches: [main] paths: - - 'HypnoScript.Dokumentation/**' - - '.github/workflows/deploy-docs.yml' + - "hypnoscript-docs/**" + - ".github/workflows/deploy-docs.yml" + - "hypnoscript-*/src/**" + - "README.md" pull_request: branches: [main] paths: - - 'HypnoScript.Dokumentation/**' + - "hypnoscript-docs/**" + - "hypnoscript-*/src/**" jobs: - build-and-deploy: + build: runs-on: ubuntu-latest + env: + RUST_DOC_SRC: target/doc + RUST_DOC_OUTPUT: rust-docs steps: - name: Checkout uses: actions/checkout@v4 + with: + fetch-depth: 0 # Für VitePress lastUpdated-Feature + + - name: Setup Rust + uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: stable + + - name: Build Rust documentation + run: | + cargo doc --no-deps --workspace --release + + - name: Ensure rust source dir exists + run: | + if [ ! -d "${RUST_DOC_SRC}" ]; then + echo "'rust-src-dir' does not point to an existing directory" + echo "The value of 'rust-src-dir' is: ${RUST_DOC_SRC}" + exit 1 + fi + mkdir -p "${RUST_DOC_OUTPUT}" + cp -r "${RUST_DOC_SRC}/." "${RUST_DOC_OUTPUT}/" - name: Setup Node.js uses: actions/setup-node@v4 with: - node-version: '18' - cache: 'npm' - cache-dependency-path: HypnoScript.Dokumentation/package-lock.json + node-version: "20" + cache: "npm" + cache-dependency-path: hypnoscript-docs/package-lock.json + + - name: Setup Pages + uses: actions/configure-pages@v4 - name: Install Dependencies - working-directory: HypnoScript.Dokumentation + working-directory: hypnoscript-docs run: npm ci - - name: Build Documentation - working-directory: HypnoScript.Dokumentation + - name: Build VitePress Documentation + working-directory: hypnoscript-docs run: npm run build - - name: Deploy to GitHub Pages - if: github.ref == 'refs/heads/main' - uses: peaceiris/actions-gh-pages@v3 + - name: Copy Rust docs to build directory + run: | + mkdir -p hypnoscript-docs/docs/.vitepress/dist/rust-api + cp -r "${RUST_DOC_OUTPUT}/." hypnoscript-docs/docs/.vitepress/dist/rust-api/ + + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./HypnoScript.Dokumentation/build - destination_dir: . + path: hypnoscript-docs/docs/.vitepress/dist + + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + needs: build + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/main' + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 # Optional: Build and test on PR test-build: runs-on: ubuntu-latest if: github.event_name == 'pull_request' + env: + RUST_DOC_SRC: target/doc + RUST_DOC_OUTPUT: rust-docs steps: - name: Checkout uses: actions/checkout@v4 + - name: Setup Rust + uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: stable + + - name: Build Rust documentation + run: cargo doc --no-deps --workspace --release + + - name: Ensure rust source dir exists + run: | + if [ ! -d "${RUST_DOC_SRC}" ]; then + echo "'rust-src-dir' does not point to an existing directory" + echo "The value of 'rust-src-dir' is: ${RUST_DOC_SRC}" + exit 1 + fi + mkdir -p "${RUST_DOC_OUTPUT}" + cp -r "${RUST_DOC_SRC}/." "${RUST_DOC_OUTPUT}/" + - name: Setup Node.js uses: actions/setup-node@v4 with: - node-version: '18' - cache: 'npm' - cache-dependency-path: HypnoScript.Dokumentation/package-lock.json + node-version: "20" + cache: "npm" + cache-dependency-path: hypnoscript-docs/package-lock.json - name: Install Dependencies - working-directory: HypnoScript.Dokumentation + working-directory: hypnoscript-docs run: npm ci - - name: Build Documentation - working-directory: HypnoScript.Dokumentation + - name: Build VitePress Documentation + working-directory: hypnoscript-docs run: npm run build - name: Check for broken links - working-directory: HypnoScript.Dokumentation + working-directory: hypnoscript-docs run: | - npm install -g broken-link-checker - blc http://localhost:3000 -ro + npm install --no-save linkinator@^3 wait-on@^7 + npx vitepress preview docs --host 127.0.0.1 --port 4173 & + PREVIEW_PID=$! + trap 'kill $PREVIEW_PID 2>/dev/null || true' EXIT + npx wait-on http://127.0.0.1:4173/hyp-runtime/ + npx linkinator http://127.0.0.1:4173/hyp-runtime/ --recurse --skip "^mailto:" + kill $PREVIEW_PID 2>/dev/null || true + wait $PREVIEW_PID 2>/dev/null || true + trap - EXIT diff --git a/.github/workflows/rust-build-and-release.yml b/.github/workflows/rust-build-and-release.yml new file mode 100644 index 0000000..69534a4 --- /dev/null +++ b/.github/workflows/rust-build-and-release.yml @@ -0,0 +1,239 @@ +name: Rust Build & Release HypnoScript + +on: + push: + tags: + - 'v*.*.*' + - 'rust-v*.*.*' + +jobs: + build-release: + runs-on: ${{ matrix.os }} + strategy: + matrix: + include: + - os: ubuntu-latest + target: x86_64-unknown-linux-gnu + artifact_name: hypnoscript-cli + asset_name: hypnoscript-linux-x64 + - os: ubuntu-latest + target: x86_64-unknown-linux-musl + artifact_name: hypnoscript-cli + asset_name: hypnoscript-linux-x64-musl + - os: windows-latest + target: x86_64-pc-windows-msvc + artifact_name: hypnoscript-cli.exe + asset_name: hypnoscript-windows-x64.exe + - os: macos-latest + target: x86_64-apple-darwin + artifact_name: hypnoscript-cli + asset_name: hypnoscript-macos-x64 + - os: macos-latest + target: aarch64-apple-darwin + artifact_name: hypnoscript-cli + asset_name: hypnoscript-macos-arm64 + + env: + CARGO_TERM_COLOR: always + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Rust + uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: stable + target: ${{ matrix.target }} + + - name: Install musl-tools (Linux musl only) + if: matrix.target == 'x86_64-unknown-linux-musl' + run: | + sudo apt-get update + sudo apt-get install -y musl-tools + + - name: Build release binary + run: cargo build --release --target ${{ matrix.target }} --package hypnoscript-cli + + - name: Strip binary (Unix) + if: runner.os != 'Windows' + run: strip target/${{ matrix.target }}/release/${{ matrix.artifact_name }} + + - name: Create archive + shell: bash + run: | + mkdir -p dist + if [ "${{ runner.os }}" == "Windows" ]; then + cp target/${{ matrix.target }}/release/${{ matrix.artifact_name }} dist/${{ matrix.asset_name }} + cd dist + 7z a ../${{ matrix.asset_name }}.zip ${{ matrix.asset_name }} + else + cp target/${{ matrix.target }}/release/${{ matrix.artifact_name }} dist/${{ matrix.asset_name }} + cd dist + tar -czf ../${{ matrix.asset_name }}.tar.gz ${{ matrix.asset_name }} + fi + + - name: Compute SHA256 + shell: bash + run: | + if [ "${{ runner.os }}" == "Windows" ]; then + sha256sum ${{ matrix.asset_name }}.zip > ${{ matrix.asset_name }}.sha256 + else + sha256sum ${{ matrix.asset_name }}.tar.gz > ${{ matrix.asset_name }}.sha256 + fi + + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.asset_name }} + path: | + ${{ matrix.asset_name }}.* + + build-deb-package: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Rust + uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: stable + + - name: Install cargo-deb + run: cargo install cargo-deb + + - name: Create Cargo.toml metadata for debian package + run: | + cat >> hypnoscript-cli/Cargo.toml << 'EOF' + + [package.metadata.deb] + maintainer = "HypnoScript Team" + copyright = "2024, HypnoScript Team" + license-file = ["LICENSE", "0"] + extended-description = """\ + HypnoScript is a programming language designed for hypnotic induction and trance work. + This package provides the Rust-based runtime and CLI tools.""" + section = "devel" + priority = "optional" + assets = [ + ["target/release/hypnoscript-cli", "usr/bin/", "755"], + ["README.md", "usr/share/doc/hypnoscript/", "644"], + ["RUST_README.md", "usr/share/doc/hypnoscript/", "644"], + ] + EOF + + - name: Build .deb package + run: cargo deb --package hypnoscript-cli + + - name: Upload .deb artifact + uses: actions/upload-artifact@v4 + with: + name: hypnoscript-deb + path: target/debian/*.deb + + create-release: + needs: [build-release, build-deb-package] + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Download all artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts + + - name: Display structure of downloaded files + run: ls -R artifacts + + - name: Create Release + uses: softprops/action-gh-release@v1 + with: + files: | + artifacts/**/* + body: | + # HypnoScript Rust Release + + This release contains the Rust-based HypnoScript runtime and CLI tools. + + ## Features + - ✅ Complete HypnoScript language implementation + - ✅ Full compiler (Lexer, Parser, Type Checker, Interpreter, WASM Codegen) + - ✅ 110+ builtin functions + - ✅ Cross-platform support (Windows, Linux, macOS) + - ✅ Native performance (no GC overhead) + - ✅ Memory safe by design + + ## Downloads + Choose the appropriate binary for your platform: + - **Linux x64**: hypnoscript-linux-x64.tar.gz + - **Linux x64 (musl)**: hypnoscript-linux-x64-musl.tar.gz (static binary) + - **Windows x64**: hypnoscript-windows-x64.zip + - **macOS x64**: hypnoscript-macos-x64.tar.gz + - **macOS ARM64**: hypnoscript-macos-arm64.tar.gz + - **Debian/Ubuntu**: hypnoscript_*.deb + + ## Installation + + ### Linux/macOS + ```bash + # Extract the archive + tar -xzf hypnoscript-*.tar.gz + + # Move to PATH + sudo mv hypnoscript-* /usr/local/bin/hypnoscript-cli + + # Test installation + hypnoscript-cli version + ``` + + ### Windows + ```powershell + # Extract the zip + # Add to PATH or run directly + .\hypnoscript-windows-x64.exe version + ``` + + ### Debian/Ubuntu + ```bash + sudo dpkg -i hypnoscript_*.deb + hypnoscript-cli version + ``` + + ## Checksums + SHA256 checksums are provided for all binaries. Verify with: + ```bash + sha256sum -c hypnoscript-*.sha256 + ``` + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + publish-crates: + needs: create-release + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/v') + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Rust + uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: stable + + - name: Publish to crates.io + run: | + cargo publish --package hypnoscript-core --token ${{ secrets.CARGO_TOKEN }} || true + sleep 10 + cargo publish --package hypnoscript-lexer-parser --token ${{ secrets.CARGO_TOKEN }} || true + sleep 10 + cargo publish --package hypnoscript-runtime --token ${{ secrets.CARGO_TOKEN }} || true + sleep 10 + cargo publish --package hypnoscript-compiler --token ${{ secrets.CARGO_TOKEN }} || true + sleep 10 + cargo publish --package hypnoscript-cli --token ${{ secrets.CARGO_TOKEN }} || true + continue-on-error: true diff --git a/.github/workflows/rust-build-and-test.yml b/.github/workflows/rust-build-and-test.yml new file mode 100644 index 0000000..ab61ddb --- /dev/null +++ b/.github/workflows/rust-build-and-test.yml @@ -0,0 +1,247 @@ +name: Rust Build and Test + +on: + push: + branches: [main, develop] + pull_request: + branches: [main, develop] + +jobs: + build-and-test: + runs-on: ${{ matrix.os }} + + strategy: + matrix: + os: [windows-latest, ubuntu-latest, macos-latest] + rust-version: ["stable"] + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Rust + uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: ${{ matrix.rust-version }} + components: rustfmt, clippy + + - name: Cache cargo registry + uses: actions/cache@v4 + with: + path: ~/.cargo/registry + key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + ${{ runner.os }}-cargo-registry- + + - name: Cache cargo index + uses: actions/cache@v4 + with: + path: ~/.cargo/git + key: ${{ runner.os }}-cargo-git-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + ${{ runner.os }}-cargo-git- + + - name: Cache cargo build + uses: actions/cache@v4 + with: + path: target + key: ${{ runner.os }}-cargo-build-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + ${{ runner.os }}-cargo-build- + + - name: Check formatting + run: cargo fmt --all -- --check + + - name: Run clippy + run: cargo clippy --all-targets --all-features -- -D warnings + + - name: Build workspace + run: cargo build --release --workspace + + - name: Run tests + run: cargo test --workspace --verbose + + - name: Run integration tests + run: | + cargo test --package hypnoscript-lexer-parser --verbose + cargo test --package hypnoscript-compiler --verbose + cargo test --package hypnoscript-runtime --verbose + + - name: Build CLI binary + run: cargo build --release --package hypnoscript-cli + + - name: Test CLI functionality (Unix) + if: runner.os != 'Windows' + run: | + ./target/release/hypnoscript-cli version + ./target/release/hypnoscript-cli builtins + ./target/release/hypnoscript-cli lex hypnoscript-tests/test_rust_demo.hyp + ./target/release/hypnoscript-cli parse hypnoscript-tests/test_rust_demo.hyp + ./target/release/hypnoscript-cli check hypnoscript-tests/test_rust_demo.hyp + ./target/release/hypnoscript-cli run hypnoscript-tests/test_rust_demo.hyp + + - name: Test CLI functionality (Windows) + if: runner.os == 'Windows' + run: | + .\target\release\hypnoscript-cli.exe version + .\target\release\hypnoscript-cli.exe builtins + .\target\release\hypnoscript-cli.exe lex hypnoscript-tests\test_rust_demo.hyp + .\target\release\hypnoscript-cli.exe parse hypnoscript-tests\test_rust_demo.hyp + .\target\release\hypnoscript-cli.exe check hypnoscript-tests\test_rust_demo.hyp + .\target\release\hypnoscript-cli.exe run hypnoscript-tests\test_rust_demo.hyp + + - name: Upload test results + uses: actions/upload-artifact@v4 + if: always() + with: + name: test-results-${{ matrix.os }} + path: | + target/debug/ + **/test-results.xml + + - name: Upload CLI binary + uses: actions/upload-artifact@v4 + with: + name: hypnoscript-cli-${{ matrix.os }} + path: | + target/release/hypnoscript-cli* + + code-quality: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Rust + uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: stable + components: rustfmt, clippy + + - name: Install CodeQL + uses: github/codeql-action/init@v3 + with: + languages: rust + + - name: Build for CodeQL + run: cargo build --release --workspace + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 + + - name: Run security audit + run: | + cargo install cargo-audit + cargo audit + + - name: Check for unsafe code + run: | + if git grep -n "unsafe" -- '*.rs'; then + echo "Warning: Found unsafe code blocks" + else + echo "No unsafe code detected" + fi + + - name: Run cargo deny + run: | + cargo install cargo-deny + cargo deny check + + performance: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Rust + uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: stable + + - name: Build release + run: cargo build --release --workspace + + - name: Run benchmark tests + run: | + cargo test --release --package hypnoscript-runtime -- --ignored --nocapture + + - name: Generate performance report + run: | + ./target/release/hypnoscript-cli run hypnoscript-tests/test_rust_demo.hyp --verbose + time ./target/release/hypnoscript-cli run hypnoscript-tests/test_rust_demo.hyp + + - name: Upload performance results + uses: actions/upload-artifact@v4 + with: + name: performance-results + path: | + target/release/ + **/benchmark-results/ + + coverage: + runs-on: ubuntu-latest + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Rust + uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: stable + components: llvm-tools-preview + + - name: Install cargo-llvm-cov + run: cargo install cargo-llvm-cov + + - name: Generate coverage + run: cargo llvm-cov --all-features --workspace --lcov --output-path lcov.info + + - name: Upload coverage to Codecov + if: env.CODECOV_TOKEN != '' + uses: codecov/codecov-action@v4 + with: + files: lcov.info + fail_ci_if_error: true + token: ${{ env.CODECOV_TOKEN }} + + - name: Skip Codecov upload (token missing) + if: env.CODECOV_TOKEN == '' + run: | + echo "::warning::CODECOV_TOKEN secret not set; skipping Codecov upload." + + deployment: + needs: [build-and-test, code-quality, performance] + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/main' + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Rust + uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: stable + + - name: Build for release + run: cargo build --release --workspace + + - name: Create release package + run: | + mkdir -p release + cp target/release/hypnoscript-cli release/ + cp README.md release/ + cp RUST_README.md release/ || true + cp LICENSE release/ || true + tar -czf hypnoscript-rust-release.tar.gz -C release . + + - name: Upload release artifacts + uses: actions/upload-artifact@v4 + with: + name: rust-release-package + path: hypnoscript-rust-release.tar.gz diff --git a/.gitignore b/.gitignore index 6187028..08acf5e 100644 --- a/.gitignore +++ b/.gitignore @@ -72,4 +72,8 @@ artifacts/ .builds *.pidb *.svclog -*.scc \ No newline at end of file +*.scc + +# Rust +target/ +Cargo.lock diff --git a/CLI_README.md b/CLI_README.md deleted file mode 100644 index 87715da..0000000 --- a/CLI_README.md +++ /dev/null @@ -1,247 +0,0 @@ -# HypnoScript CLI - Runtime Edition - -Eine vollständige Command-Line-Interface für die HypnoScript-Programmiersprache mit drei Hauptmodi: Run, Compile und Analyze. - -## Installation - -```bash -# Projekt klonen und bauen -git clone -cd hyp-runtime -dotnet build -``` - -## Verwendung - -### Grundlegende Syntax - -```bash -dotnet run --project HypnoScript.CLI [--debug] -``` - -### Verfügbare Befehle - -#### 1. Run - Programm ausführen - -Führt HypnoScript-Code direkt aus. - -```bash -# Einfache Ausführung -dotnet run --project HypnoScript.CLI run test_simple.hyp - -# Mit Debug-Ausgaben -dotnet run --project HypnoScript.CLI run test_simple.hyp --debug -``` - -**Features:** - -- ✅ Lexikalische Analyse (Tokenisierung) -- ✅ Syntax-Analyse (Parsing) -- ✅ Typüberprüfung (TypeChecking) -- ✅ Interpreter-Ausführung -- ✅ Detaillierte Fehlerberichte - -#### 2. Compile - Zu WASM kompilieren - -Kompiliert HypnoScript-Code zu WebAssembly (WAT-Format). - -```bash -# Kompilierung -dotnet run --project HypnoScript.CLI compile test_advanced.hyp - -# Mit Debug-Ausgaben -dotnet run --project HypnoScript.CLI compile test_advanced.hyp --debug -``` - -**Features:** - -- ✅ WASM Code Generation -- ✅ WAT-Format Ausgabe -- ✅ Automatische Datei-Erweiterung (.wat) -- ✅ Optimierte Code-Generierung - -#### 3. Analyze - Statische Analyse - -Führt eine umfassende statische Analyse durch. - -```bash -# Analyse -dotnet run --project HypnoScript.CLI analyze test_advanced.hyp - -# Mit Debug-Ausgaben -dotnet run --project HypnoScript.CLI analyze test_advanced.hyp --debug -``` - -**Features:** - -- 📊 Token-Analyse (Häufigkeit, Typen) -- 🌳 AST-Analyse (Statement-Typen) -- 📈 Code-Metriken (Zeilen, Zeichen, Tokens) -- ✅ Typüberprüfung -- 📋 Detaillierte Berichte - -## Beispiele - -### Einfaches Programm (test_simple.hyp) - -```hypno -Focus { - observe "Hello World!"; -} Relax -``` - -### Erweitertes Programm (test_advanced.hyp) - -```hypno -Focus { - entrance { - observe "Willkommen in der erweiterten HypnoScript-Welt!"; - drift(1000); - } - - induce x: number = 10; - induce y: number = 5; - - if (x > 5) deepFocus { - observe "x ist größer als 5"; - } - - while (y > 0) { - observe "Countdown: " + y; - y = y - 1; - } -} Relax -``` - -## Ausgabe-Beispiele - -### Run-Modus - -```bash -=== RUN MODE === -✓ Datei beginnt mit 'Focus' - Syntax OK -✓ Lexing erfolgreich! -✓ Parsing erfolgreich! -✓ TypeChecking erfolgreich! -✓ Ausführung erfolgreich! -🎉 HypnoScript-Programm erfolgreich ausgeführt! -``` - -### Compile-Modus - -```bash -=== COMPILE MODE === -✓ Lexing erfolgreich! -✓ Parsing erfolgreich! -✓ WASM Code Generation erfolgreich! -📁 WASM (WAT) Code gespeichert: test_advanced.wat -🎉 Kompilierung erfolgreich abgeschlossen! -``` - -### Analyze-Modus - -```bash -=== ANALYZE MODE === -✓ Lexing erfolgreich! - -📊 TOKEN-ANALYSE: - Identifier: 15x - StringLiteral: 8x - NumberLiteral: 6x - LBrace: 5x - RBrace: 5x - ... - -🌳 AST-ANALYSE: - Top-Level Statements: 12 - ExpressionStatementNode: 8x - VarDeclNode: 4x - -📈 CODE-METRIKEN: - Zeilen: 25 - Zeichen: 456 - Tokens: 67 - Statements: 12 - -🎉 Statische Analyse erfolgreich abgeschlossen! -``` - -## Fehlerbehandlung - -Die CLI bietet umfassende Fehlerbehandlung: - -- **Datei nicht gefunden**: Exit Code 2 -- **Syntax-Fehler**: Detaillierte Fehlermeldungen mit Zeilen-/Spaltenangaben -- **Typ-Fehler**: Spezifische Typfehler mit Kontext -- **Runtime-Fehler**: Ausführungsfehler mit Stack-Trace (im Debug-Modus) - -## Debug-Modus - -Der `--debug` Flag aktiviert zusätzliche Ausgaben: - -- Detaillierte Verarbeitungsschritte -- Token-Details -- AST-Struktur -- Stack-Traces bei Fehlern -- Performance-Metriken - -## Exit Codes - -- **0**: Erfolg -- **1**: Fehler (Syntax, Typ, Runtime) -- **2**: Datei nicht gefunden -- **99**: Fataler Fehler - -## Erweiterte Features - -### Unterstützte Sprachkonstrukte - -- ✅ Variablen (`induce`) -- ✅ Kontrollstrukturen (`if`, `while`, `loop`) -- ✅ Funktionen (`suggestion`) -- ✅ Arrays und Listen -- ✅ Strings und Zahlen -- ✅ Hypnotische Operatoren -- ✅ Sessions und Tranceify -- ✅ Built-in Funktionen - -### Performance-Optimierungen - -- Effiziente Tokenisierung -- Optimierte AST-Erstellung -- Schnelle Typüberprüfung -- Minimaler Speicherverbrauch - -## Entwicklung - -### Projektstruktur - -```bash -HypnoScript.CLI/ -├── Program.cs # Haupt-CLI-Logik -├── HypnoScript.CLI.csproj -└── ... - -HypnoScript.LexerParser/ -├── Lexer/ # Tokenisierung -├── Parser/ # Syntax-Analyse -└── AST/ # Abstract Syntax Tree - -HypnoScript.Compiler/ -├── Analysis/ # Typüberprüfung -├── Interpreter/ # Ausführung -└── CodeGen/ # WASM-Generierung -``` - -### Erweitern der CLI - -Neue Befehle können einfach hinzugefügt werden: - -1. Neuen Case im `Main` Switch hinzufügen -2. Neue Methode für den Befehl erstellen -3. `ShowUsage()` aktualisieren - -## Lizenz - -HypnoScript CLI - Runtime Edition -Copyright (c) 2024 HypnoScript Team diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..1ec5239 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,29 @@ +[workspace] +resolver = "2" +members = [ + "hypnoscript-core", + "hypnoscript-lexer-parser", + "hypnoscript-compiler", + "hypnoscript-runtime", + "hypnoscript-cli", +] + +[workspace.package] +version = "1.0.0" +edition = "2021" +authors = ["Kink Development Group"] +license = "MIT" +repository = "https://github.com/Kink-Development-Group/hyp-runtime" + +[workspace.dependencies] +# Core dependencies shared across workspace +anyhow = "1.0" +thiserror = "1.0" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" + +[profile.release] +opt-level = 3 +lto = true +codegen-units = 1 +strip = true diff --git a/HypnoScript.CLI.Tests/HypnoScript.CLI.Tests.csproj b/HypnoScript.CLI.Tests/HypnoScript.CLI.Tests.csproj deleted file mode 100644 index 90b7920..0000000 --- a/HypnoScript.CLI.Tests/HypnoScript.CLI.Tests.csproj +++ /dev/null @@ -1,31 +0,0 @@ - - - - net9.0 - enable - enable - false - - - - - - - - - - - - - - - - - - - - PreserveNewest - - - - diff --git a/HypnoScript.CLI.Tests/README.md b/HypnoScript.CLI.Tests/README.md deleted file mode 100644 index e20f190..0000000 --- a/HypnoScript.CLI.Tests/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# HypnoScript.CLI.Tests – Teststrategie - -Dieses Testprojekt stellt die Integrationstests für die wichtigsten CLI-Kommandos von HypnoScript bereit. - -## Ziele - -- Sicherstellen, dass die CLI-Kommandos (lint, benchmark, profile, optimize) mit echten Skripten korrekt funktionieren. -- Fehlerfälle und Grenzfälle automatisiert abdecken. -- Testdaten und -skripte sind im Verzeichnis `TestData` getrennt abgelegt. - -## Teststruktur - -- **TestData/**: Enthält Beispielskripte für valide und fehlerhafte HypnoScript-Programme. -- **UnitTest1.cs**: Enthält Integrationstests für die CLI-Kommandos. Jeder Test prüft den Rückgabewert und damit die Fehlererkennung. - -## Erweiterung - -- Weitere Tests für Grenzfälle (leere Datei, große Skripte, ungültige Syntax) können einfach ergänzt werden. -- Neue Kommandos sollten durch eigene Integrationstests abgedeckt werden. - -## Ausführung - -Die Tests können mit folgendem Befehl ausgeführt werden: - - dotnet test HypnoScript.CLI.Tests/HypnoScript.CLI.Tests.csproj diff --git a/HypnoScript.CLI.Tests/TestData/comments_only.hyp b/HypnoScript.CLI.Tests/TestData/comments_only.hyp deleted file mode 100644 index b5359af..0000000 --- a/HypnoScript.CLI.Tests/TestData/comments_only.hyp +++ /dev/null @@ -1 +0,0 @@ -// This is a comment\n// Another comment\n \n\t// Whitespace and tabs\n diff --git a/HypnoScript.CLI.Tests/TestData/empty.hyp b/HypnoScript.CLI.Tests/TestData/empty.hyp deleted file mode 100644 index 0519ecb..0000000 --- a/HypnoScript.CLI.Tests/TestData/empty.hyp +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/HypnoScript.CLI.Tests/TestData/invalid.hyp b/HypnoScript.CLI.Tests/TestData/invalid.hyp deleted file mode 100644 index 05a8220..0000000 --- a/HypnoScript.CLI.Tests/TestData/invalid.hyp +++ /dev/null @@ -1 +0,0 @@ -Focus { induce x = ; } Relax diff --git a/HypnoScript.CLI.Tests/TestData/invalid_block.hyp b/HypnoScript.CLI.Tests/TestData/invalid_block.hyp deleted file mode 100644 index 6513cf9..0000000 --- a/HypnoScript.CLI.Tests/TestData/invalid_block.hyp +++ /dev/null @@ -1 +0,0 @@ -Focus { induce x: number = 5; induce y: string = \"test\" Relax diff --git a/HypnoScript.CLI.Tests/TestData/large.hyp b/HypnoScript.CLI.Tests/TestData/large.hyp deleted file mode 100644 index a525f9d..0000000 --- a/HypnoScript.CLI.Tests/TestData/large.hyp +++ /dev/null @@ -1,1002 +0,0 @@ -Focus { - induce v0: number = 0; - induce v1: number = 1; - induce v2: number = 2; - induce v3: number = 3; - induce v4: number = 4; - induce v5: number = 5; - induce v6: number = 6; - induce v7: number = 7; - induce v8: number = 8; - induce v9: number = 9; - induce v10: number = 10; - induce v11: number = 11; - induce v12: number = 12; - induce v13: number = 13; - induce v14: number = 14; - induce v15: number = 15; - induce v16: number = 16; - induce v17: number = 17; - induce v18: number = 18; - induce v19: number = 19; - induce v20: number = 20; - induce v21: number = 21; - induce v22: number = 22; - induce v23: number = 23; - induce v24: number = 24; - induce v25: number = 25; - induce v26: number = 26; - induce v27: number = 27; - induce v28: number = 28; - induce v29: number = 29; - induce v30: number = 30; - induce v31: number = 31; - induce v32: number = 32; - induce v33: number = 33; - induce v34: number = 34; - induce v35: number = 35; - induce v36: number = 36; - induce v37: number = 37; - induce v38: number = 38; - induce v39: number = 39; - induce v40: number = 40; - induce v41: number = 41; - induce v42: number = 42; - induce v43: number = 43; - induce v44: number = 44; - induce v45: number = 45; - induce v46: number = 46; - induce v47: number = 47; - induce v48: number = 48; - induce v49: number = 49; - induce v50: number = 50; - induce v51: number = 51; - induce v52: number = 52; - induce v53: number = 53; - induce v54: number = 54; - induce v55: number = 55; - induce v56: number = 56; - induce v57: number = 57; - induce v58: number = 58; - induce v59: number = 59; - induce v60: number = 60; - induce v61: number = 61; - induce v62: number = 62; - induce v63: number = 63; - induce v64: number = 64; - induce v65: number = 65; - induce v66: number = 66; - induce v67: number = 67; - induce v68: number = 68; - induce v69: number = 69; - induce v70: number = 70; - induce v71: number = 71; - induce v72: number = 72; - induce v73: number = 73; - induce v74: number = 74; - induce v75: number = 75; - induce v76: number = 76; - induce v77: number = 77; - induce v78: number = 78; - induce v79: number = 79; - induce v80: number = 80; - induce v81: number = 81; - induce v82: number = 82; - induce v83: number = 83; - induce v84: number = 84; - induce v85: number = 85; - induce v86: number = 86; - induce v87: number = 87; - induce v88: number = 88; - induce v89: number = 89; - induce v90: number = 90; - induce v91: number = 91; - induce v92: number = 92; - induce v93: number = 93; - induce v94: number = 94; - induce v95: number = 95; - induce v96: number = 96; - induce v97: number = 97; - induce v98: number = 98; - induce v99: number = 99; - induce v100: number = 100; - induce v101: number = 101; - induce v102: number = 102; - induce v103: number = 103; - induce v104: number = 104; - induce v105: number = 105; - induce v106: number = 106; - induce v107: number = 107; - induce v108: number = 108; - induce v109: number = 109; - induce v110: number = 110; - induce v111: number = 111; - induce v112: number = 112; - induce v113: number = 113; - induce v114: number = 114; - induce v115: number = 115; - induce v116: number = 116; - induce v117: number = 117; - induce v118: number = 118; - induce v119: number = 119; - induce v120: number = 120; - induce v121: number = 121; - induce v122: number = 122; - induce v123: number = 123; - induce v124: number = 124; - induce v125: number = 125; - induce v126: number = 126; - induce v127: number = 127; - induce v128: number = 128; - induce v129: number = 129; - induce v130: number = 130; - induce v131: number = 131; - induce v132: number = 132; - induce v133: number = 133; - induce v134: number = 134; - induce v135: number = 135; - induce v136: number = 136; - induce v137: number = 137; - induce v138: number = 138; - induce v139: number = 139; - induce v140: number = 140; - induce v141: number = 141; - induce v142: number = 142; - induce v143: number = 143; - induce v144: number = 144; - induce v145: number = 145; - induce v146: number = 146; - induce v147: number = 147; - induce v148: number = 148; - induce v149: number = 149; - induce v150: number = 150; - induce v151: number = 151; - induce v152: number = 152; - induce v153: number = 153; - induce v154: number = 154; - induce v155: number = 155; - induce v156: number = 156; - induce v157: number = 157; - induce v158: number = 158; - induce v159: number = 159; - induce v160: number = 160; - induce v161: number = 161; - induce v162: number = 162; - induce v163: number = 163; - induce v164: number = 164; - induce v165: number = 165; - induce v166: number = 166; - induce v167: number = 167; - induce v168: number = 168; - induce v169: number = 169; - induce v170: number = 170; - induce v171: number = 171; - induce v172: number = 172; - induce v173: number = 173; - induce v174: number = 174; - induce v175: number = 175; - induce v176: number = 176; - induce v177: number = 177; - induce v178: number = 178; - induce v179: number = 179; - induce v180: number = 180; - induce v181: number = 181; - induce v182: number = 182; - induce v183: number = 183; - induce v184: number = 184; - induce v185: number = 185; - induce v186: number = 186; - induce v187: number = 187; - induce v188: number = 188; - induce v189: number = 189; - induce v190: number = 190; - induce v191: number = 191; - induce v192: number = 192; - induce v193: number = 193; - induce v194: number = 194; - induce v195: number = 195; - induce v196: number = 196; - induce v197: number = 197; - induce v198: number = 198; - induce v199: number = 199; - induce v200: number = 200; - induce v201: number = 201; - induce v202: number = 202; - induce v203: number = 203; - induce v204: number = 204; - induce v205: number = 205; - induce v206: number = 206; - induce v207: number = 207; - induce v208: number = 208; - induce v209: number = 209; - induce v210: number = 210; - induce v211: number = 211; - induce v212: number = 212; - induce v213: number = 213; - induce v214: number = 214; - induce v215: number = 215; - induce v216: number = 216; - induce v217: number = 217; - induce v218: number = 218; - induce v219: number = 219; - induce v220: number = 220; - induce v221: number = 221; - induce v222: number = 222; - induce v223: number = 223; - induce v224: number = 224; - induce v225: number = 225; - induce v226: number = 226; - induce v227: number = 227; - induce v228: number = 228; - induce v229: number = 229; - induce v230: number = 230; - induce v231: number = 231; - induce v232: number = 232; - induce v233: number = 233; - induce v234: number = 234; - induce v235: number = 235; - induce v236: number = 236; - induce v237: number = 237; - induce v238: number = 238; - induce v239: number = 239; - induce v240: number = 240; - induce v241: number = 241; - induce v242: number = 242; - induce v243: number = 243; - induce v244: number = 244; - induce v245: number = 245; - induce v246: number = 246; - induce v247: number = 247; - induce v248: number = 248; - induce v249: number = 249; - induce v250: number = 250; - induce v251: number = 251; - induce v252: number = 252; - induce v253: number = 253; - induce v254: number = 254; - induce v255: number = 255; - induce v256: number = 256; - induce v257: number = 257; - induce v258: number = 258; - induce v259: number = 259; - induce v260: number = 260; - induce v261: number = 261; - induce v262: number = 262; - induce v263: number = 263; - induce v264: number = 264; - induce v265: number = 265; - induce v266: number = 266; - induce v267: number = 267; - induce v268: number = 268; - induce v269: number = 269; - induce v270: number = 270; - induce v271: number = 271; - induce v272: number = 272; - induce v273: number = 273; - induce v274: number = 274; - induce v275: number = 275; - induce v276: number = 276; - induce v277: number = 277; - induce v278: number = 278; - induce v279: number = 279; - induce v280: number = 280; - induce v281: number = 281; - induce v282: number = 282; - induce v283: number = 283; - induce v284: number = 284; - induce v285: number = 285; - induce v286: number = 286; - induce v287: number = 287; - induce v288: number = 288; - induce v289: number = 289; - induce v290: number = 290; - induce v291: number = 291; - induce v292: number = 292; - induce v293: number = 293; - induce v294: number = 294; - induce v295: number = 295; - induce v296: number = 296; - induce v297: number = 297; - induce v298: number = 298; - induce v299: number = 299; - induce v300: number = 300; - induce v301: number = 301; - induce v302: number = 302; - induce v303: number = 303; - induce v304: number = 304; - induce v305: number = 305; - induce v306: number = 306; - induce v307: number = 307; - induce v308: number = 308; - induce v309: number = 309; - induce v310: number = 310; - induce v311: number = 311; - induce v312: number = 312; - induce v313: number = 313; - induce v314: number = 314; - induce v315: number = 315; - induce v316: number = 316; - induce v317: number = 317; - induce v318: number = 318; - induce v319: number = 319; - induce v320: number = 320; - induce v321: number = 321; - induce v322: number = 322; - induce v323: number = 323; - induce v324: number = 324; - induce v325: number = 325; - induce v326: number = 326; - induce v327: number = 327; - induce v328: number = 328; - induce v329: number = 329; - induce v330: number = 330; - induce v331: number = 331; - induce v332: number = 332; - induce v333: number = 333; - induce v334: number = 334; - induce v335: number = 335; - induce v336: number = 336; - induce v337: number = 337; - induce v338: number = 338; - induce v339: number = 339; - induce v340: number = 340; - induce v341: number = 341; - induce v342: number = 342; - induce v343: number = 343; - induce v344: number = 344; - induce v345: number = 345; - induce v346: number = 346; - induce v347: number = 347; - induce v348: number = 348; - induce v349: number = 349; - induce v350: number = 350; - induce v351: number = 351; - induce v352: number = 352; - induce v353: number = 353; - induce v354: number = 354; - induce v355: number = 355; - induce v356: number = 356; - induce v357: number = 357; - induce v358: number = 358; - induce v359: number = 359; - induce v360: number = 360; - induce v361: number = 361; - induce v362: number = 362; - induce v363: number = 363; - induce v364: number = 364; - induce v365: number = 365; - induce v366: number = 366; - induce v367: number = 367; - induce v368: number = 368; - induce v369: number = 369; - induce v370: number = 370; - induce v371: number = 371; - induce v372: number = 372; - induce v373: number = 373; - induce v374: number = 374; - induce v375: number = 375; - induce v376: number = 376; - induce v377: number = 377; - induce v378: number = 378; - induce v379: number = 379; - induce v380: number = 380; - induce v381: number = 381; - induce v382: number = 382; - induce v383: number = 383; - induce v384: number = 384; - induce v385: number = 385; - induce v386: number = 386; - induce v387: number = 387; - induce v388: number = 388; - induce v389: number = 389; - induce v390: number = 390; - induce v391: number = 391; - induce v392: number = 392; - induce v393: number = 393; - induce v394: number = 394; - induce v395: number = 395; - induce v396: number = 396; - induce v397: number = 397; - induce v398: number = 398; - induce v399: number = 399; - induce v400: number = 400; - induce v401: number = 401; - induce v402: number = 402; - induce v403: number = 403; - induce v404: number = 404; - induce v405: number = 405; - induce v406: number = 406; - induce v407: number = 407; - induce v408: number = 408; - induce v409: number = 409; - induce v410: number = 410; - induce v411: number = 411; - induce v412: number = 412; - induce v413: number = 413; - induce v414: number = 414; - induce v415: number = 415; - induce v416: number = 416; - induce v417: number = 417; - induce v418: number = 418; - induce v419: number = 419; - induce v420: number = 420; - induce v421: number = 421; - induce v422: number = 422; - induce v423: number = 423; - induce v424: number = 424; - induce v425: number = 425; - induce v426: number = 426; - induce v427: number = 427; - induce v428: number = 428; - induce v429: number = 429; - induce v430: number = 430; - induce v431: number = 431; - induce v432: number = 432; - induce v433: number = 433; - induce v434: number = 434; - induce v435: number = 435; - induce v436: number = 436; - induce v437: number = 437; - induce v438: number = 438; - induce v439: number = 439; - induce v440: number = 440; - induce v441: number = 441; - induce v442: number = 442; - induce v443: number = 443; - induce v444: number = 444; - induce v445: number = 445; - induce v446: number = 446; - induce v447: number = 447; - induce v448: number = 448; - induce v449: number = 449; - induce v450: number = 450; - induce v451: number = 451; - induce v452: number = 452; - induce v453: number = 453; - induce v454: number = 454; - induce v455: number = 455; - induce v456: number = 456; - induce v457: number = 457; - induce v458: number = 458; - induce v459: number = 459; - induce v460: number = 460; - induce v461: number = 461; - induce v462: number = 462; - induce v463: number = 463; - induce v464: number = 464; - induce v465: number = 465; - induce v466: number = 466; - induce v467: number = 467; - induce v468: number = 468; - induce v469: number = 469; - induce v470: number = 470; - induce v471: number = 471; - induce v472: number = 472; - induce v473: number = 473; - induce v474: number = 474; - induce v475: number = 475; - induce v476: number = 476; - induce v477: number = 477; - induce v478: number = 478; - induce v479: number = 479; - induce v480: number = 480; - induce v481: number = 481; - induce v482: number = 482; - induce v483: number = 483; - induce v484: number = 484; - induce v485: number = 485; - induce v486: number = 486; - induce v487: number = 487; - induce v488: number = 488; - induce v489: number = 489; - induce v490: number = 490; - induce v491: number = 491; - induce v492: number = 492; - induce v493: number = 493; - induce v494: number = 494; - induce v495: number = 495; - induce v496: number = 496; - induce v497: number = 497; - induce v498: number = 498; - induce v499: number = 499; - induce v500: number = 500; - induce v501: number = 501; - induce v502: number = 502; - induce v503: number = 503; - induce v504: number = 504; - induce v505: number = 505; - induce v506: number = 506; - induce v507: number = 507; - induce v508: number = 508; - induce v509: number = 509; - induce v510: number = 510; - induce v511: number = 511; - induce v512: number = 512; - induce v513: number = 513; - induce v514: number = 514; - induce v515: number = 515; - induce v516: number = 516; - induce v517: number = 517; - induce v518: number = 518; - induce v519: number = 519; - induce v520: number = 520; - induce v521: number = 521; - induce v522: number = 522; - induce v523: number = 523; - induce v524: number = 524; - induce v525: number = 525; - induce v526: number = 526; - induce v527: number = 527; - induce v528: number = 528; - induce v529: number = 529; - induce v530: number = 530; - induce v531: number = 531; - induce v532: number = 532; - induce v533: number = 533; - induce v534: number = 534; - induce v535: number = 535; - induce v536: number = 536; - induce v537: number = 537; - induce v538: number = 538; - induce v539: number = 539; - induce v540: number = 540; - induce v541: number = 541; - induce v542: number = 542; - induce v543: number = 543; - induce v544: number = 544; - induce v545: number = 545; - induce v546: number = 546; - induce v547: number = 547; - induce v548: number = 548; - induce v549: number = 549; - induce v550: number = 550; - induce v551: number = 551; - induce v552: number = 552; - induce v553: number = 553; - induce v554: number = 554; - induce v555: number = 555; - induce v556: number = 556; - induce v557: number = 557; - induce v558: number = 558; - induce v559: number = 559; - induce v560: number = 560; - induce v561: number = 561; - induce v562: number = 562; - induce v563: number = 563; - induce v564: number = 564; - induce v565: number = 565; - induce v566: number = 566; - induce v567: number = 567; - induce v568: number = 568; - induce v569: number = 569; - induce v570: number = 570; - induce v571: number = 571; - induce v572: number = 572; - induce v573: number = 573; - induce v574: number = 574; - induce v575: number = 575; - induce v576: number = 576; - induce v577: number = 577; - induce v578: number = 578; - induce v579: number = 579; - induce v580: number = 580; - induce v581: number = 581; - induce v582: number = 582; - induce v583: number = 583; - induce v584: number = 584; - induce v585: number = 585; - induce v586: number = 586; - induce v587: number = 587; - induce v588: number = 588; - induce v589: number = 589; - induce v590: number = 590; - induce v591: number = 591; - induce v592: number = 592; - induce v593: number = 593; - induce v594: number = 594; - induce v595: number = 595; - induce v596: number = 596; - induce v597: number = 597; - induce v598: number = 598; - induce v599: number = 599; - induce v600: number = 600; - induce v601: number = 601; - induce v602: number = 602; - induce v603: number = 603; - induce v604: number = 604; - induce v605: number = 605; - induce v606: number = 606; - induce v607: number = 607; - induce v608: number = 608; - induce v609: number = 609; - induce v610: number = 610; - induce v611: number = 611; - induce v612: number = 612; - induce v613: number = 613; - induce v614: number = 614; - induce v615: number = 615; - induce v616: number = 616; - induce v617: number = 617; - induce v618: number = 618; - induce v619: number = 619; - induce v620: number = 620; - induce v621: number = 621; - induce v622: number = 622; - induce v623: number = 623; - induce v624: number = 624; - induce v625: number = 625; - induce v626: number = 626; - induce v627: number = 627; - induce v628: number = 628; - induce v629: number = 629; - induce v630: number = 630; - induce v631: number = 631; - induce v632: number = 632; - induce v633: number = 633; - induce v634: number = 634; - induce v635: number = 635; - induce v636: number = 636; - induce v637: number = 637; - induce v638: number = 638; - induce v639: number = 639; - induce v640: number = 640; - induce v641: number = 641; - induce v642: number = 642; - induce v643: number = 643; - induce v644: number = 644; - induce v645: number = 645; - induce v646: number = 646; - induce v647: number = 647; - induce v648: number = 648; - induce v649: number = 649; - induce v650: number = 650; - induce v651: number = 651; - induce v652: number = 652; - induce v653: number = 653; - induce v654: number = 654; - induce v655: number = 655; - induce v656: number = 656; - induce v657: number = 657; - induce v658: number = 658; - induce v659: number = 659; - induce v660: number = 660; - induce v661: number = 661; - induce v662: number = 662; - induce v663: number = 663; - induce v664: number = 664; - induce v665: number = 665; - induce v666: number = 666; - induce v667: number = 667; - induce v668: number = 668; - induce v669: number = 669; - induce v670: number = 670; - induce v671: number = 671; - induce v672: number = 672; - induce v673: number = 673; - induce v674: number = 674; - induce v675: number = 675; - induce v676: number = 676; - induce v677: number = 677; - induce v678: number = 678; - induce v679: number = 679; - induce v680: number = 680; - induce v681: number = 681; - induce v682: number = 682; - induce v683: number = 683; - induce v684: number = 684; - induce v685: number = 685; - induce v686: number = 686; - induce v687: number = 687; - induce v688: number = 688; - induce v689: number = 689; - induce v690: number = 690; - induce v691: number = 691; - induce v692: number = 692; - induce v693: number = 693; - induce v694: number = 694; - induce v695: number = 695; - induce v696: number = 696; - induce v697: number = 697; - induce v698: number = 698; - induce v699: number = 699; - induce v700: number = 700; - induce v701: number = 701; - induce v702: number = 702; - induce v703: number = 703; - induce v704: number = 704; - induce v705: number = 705; - induce v706: number = 706; - induce v707: number = 707; - induce v708: number = 708; - induce v709: number = 709; - induce v710: number = 710; - induce v711: number = 711; - induce v712: number = 712; - induce v713: number = 713; - induce v714: number = 714; - induce v715: number = 715; - induce v716: number = 716; - induce v717: number = 717; - induce v718: number = 718; - induce v719: number = 719; - induce v720: number = 720; - induce v721: number = 721; - induce v722: number = 722; - induce v723: number = 723; - induce v724: number = 724; - induce v725: number = 725; - induce v726: number = 726; - induce v727: number = 727; - induce v728: number = 728; - induce v729: number = 729; - induce v730: number = 730; - induce v731: number = 731; - induce v732: number = 732; - induce v733: number = 733; - induce v734: number = 734; - induce v735: number = 735; - induce v736: number = 736; - induce v737: number = 737; - induce v738: number = 738; - induce v739: number = 739; - induce v740: number = 740; - induce v741: number = 741; - induce v742: number = 742; - induce v743: number = 743; - induce v744: number = 744; - induce v745: number = 745; - induce v746: number = 746; - induce v747: number = 747; - induce v748: number = 748; - induce v749: number = 749; - induce v750: number = 750; - induce v751: number = 751; - induce v752: number = 752; - induce v753: number = 753; - induce v754: number = 754; - induce v755: number = 755; - induce v756: number = 756; - induce v757: number = 757; - induce v758: number = 758; - induce v759: number = 759; - induce v760: number = 760; - induce v761: number = 761; - induce v762: number = 762; - induce v763: number = 763; - induce v764: number = 764; - induce v765: number = 765; - induce v766: number = 766; - induce v767: number = 767; - induce v768: number = 768; - induce v769: number = 769; - induce v770: number = 770; - induce v771: number = 771; - induce v772: number = 772; - induce v773: number = 773; - induce v774: number = 774; - induce v775: number = 775; - induce v776: number = 776; - induce v777: number = 777; - induce v778: number = 778; - induce v779: number = 779; - induce v780: number = 780; - induce v781: number = 781; - induce v782: number = 782; - induce v783: number = 783; - induce v784: number = 784; - induce v785: number = 785; - induce v786: number = 786; - induce v787: number = 787; - induce v788: number = 788; - induce v789: number = 789; - induce v790: number = 790; - induce v791: number = 791; - induce v792: number = 792; - induce v793: number = 793; - induce v794: number = 794; - induce v795: number = 795; - induce v796: number = 796; - induce v797: number = 797; - induce v798: number = 798; - induce v799: number = 799; - induce v800: number = 800; - induce v801: number = 801; - induce v802: number = 802; - induce v803: number = 803; - induce v804: number = 804; - induce v805: number = 805; - induce v806: number = 806; - induce v807: number = 807; - induce v808: number = 808; - induce v809: number = 809; - induce v810: number = 810; - induce v811: number = 811; - induce v812: number = 812; - induce v813: number = 813; - induce v814: number = 814; - induce v815: number = 815; - induce v816: number = 816; - induce v817: number = 817; - induce v818: number = 818; - induce v819: number = 819; - induce v820: number = 820; - induce v821: number = 821; - induce v822: number = 822; - induce v823: number = 823; - induce v824: number = 824; - induce v825: number = 825; - induce v826: number = 826; - induce v827: number = 827; - induce v828: number = 828; - induce v829: number = 829; - induce v830: number = 830; - induce v831: number = 831; - induce v832: number = 832; - induce v833: number = 833; - induce v834: number = 834; - induce v835: number = 835; - induce v836: number = 836; - induce v837: number = 837; - induce v838: number = 838; - induce v839: number = 839; - induce v840: number = 840; - induce v841: number = 841; - induce v842: number = 842; - induce v843: number = 843; - induce v844: number = 844; - induce v845: number = 845; - induce v846: number = 846; - induce v847: number = 847; - induce v848: number = 848; - induce v849: number = 849; - induce v850: number = 850; - induce v851: number = 851; - induce v852: number = 852; - induce v853: number = 853; - induce v854: number = 854; - induce v855: number = 855; - induce v856: number = 856; - induce v857: number = 857; - induce v858: number = 858; - induce v859: number = 859; - induce v860: number = 860; - induce v861: number = 861; - induce v862: number = 862; - induce v863: number = 863; - induce v864: number = 864; - induce v865: number = 865; - induce v866: number = 866; - induce v867: number = 867; - induce v868: number = 868; - induce v869: number = 869; - induce v870: number = 870; - induce v871: number = 871; - induce v872: number = 872; - induce v873: number = 873; - induce v874: number = 874; - induce v875: number = 875; - induce v876: number = 876; - induce v877: number = 877; - induce v878: number = 878; - induce v879: number = 879; - induce v880: number = 880; - induce v881: number = 881; - induce v882: number = 882; - induce v883: number = 883; - induce v884: number = 884; - induce v885: number = 885; - induce v886: number = 886; - induce v887: number = 887; - induce v888: number = 888; - induce v889: number = 889; - induce v890: number = 890; - induce v891: number = 891; - induce v892: number = 892; - induce v893: number = 893; - induce v894: number = 894; - induce v895: number = 895; - induce v896: number = 896; - induce v897: number = 897; - induce v898: number = 898; - induce v899: number = 899; - induce v900: number = 900; - induce v901: number = 901; - induce v902: number = 902; - induce v903: number = 903; - induce v904: number = 904; - induce v905: number = 905; - induce v906: number = 906; - induce v907: number = 907; - induce v908: number = 908; - induce v909: number = 909; - induce v910: number = 910; - induce v911: number = 911; - induce v912: number = 912; - induce v913: number = 913; - induce v914: number = 914; - induce v915: number = 915; - induce v916: number = 916; - induce v917: number = 917; - induce v918: number = 918; - induce v919: number = 919; - induce v920: number = 920; - induce v921: number = 921; - induce v922: number = 922; - induce v923: number = 923; - induce v924: number = 924; - induce v925: number = 925; - induce v926: number = 926; - induce v927: number = 927; - induce v928: number = 928; - induce v929: number = 929; - induce v930: number = 930; - induce v931: number = 931; - induce v932: number = 932; - induce v933: number = 933; - induce v934: number = 934; - induce v935: number = 935; - induce v936: number = 936; - induce v937: number = 937; - induce v938: number = 938; - induce v939: number = 939; - induce v940: number = 940; - induce v941: number = 941; - induce v942: number = 942; - induce v943: number = 943; - induce v944: number = 944; - induce v945: number = 945; - induce v946: number = 946; - induce v947: number = 947; - induce v948: number = 948; - induce v949: number = 949; - induce v950: number = 950; - induce v951: number = 951; - induce v952: number = 952; - induce v953: number = 953; - induce v954: number = 954; - induce v955: number = 955; - induce v956: number = 956; - induce v957: number = 957; - induce v958: number = 958; - induce v959: number = 959; - induce v960: number = 960; - induce v961: number = 961; - induce v962: number = 962; - induce v963: number = 963; - induce v964: number = 964; - induce v965: number = 965; - induce v966: number = 966; - induce v967: number = 967; - induce v968: number = 968; - induce v969: number = 969; - induce v970: number = 970; - induce v971: number = 971; - induce v972: number = 972; - induce v973: number = 973; - induce v974: number = 974; - induce v975: number = 975; - induce v976: number = 976; - induce v977: number = 977; - induce v978: number = 978; - induce v979: number = 979; - induce v980: number = 980; - induce v981: number = 981; - induce v982: number = 982; - induce v983: number = 983; - induce v984: number = 984; - induce v985: number = 985; - induce v986: number = 986; - induce v987: number = 987; - induce v988: number = 988; - induce v989: number = 989; - induce v990: number = 990; - induce v991: number = 991; - induce v992: number = 992; - induce v993: number = 993; - induce v994: number = 994; - induce v995: number = 995; - induce v996: number = 996; - induce v997: number = 997; - induce v998: number = 998; - induce v999: number = 999; -} Relax diff --git a/HypnoScript.CLI.Tests/TestData/valid.hyp b/HypnoScript.CLI.Tests/TestData/valid.hyp deleted file mode 100644 index 6c22fd1..0000000 --- a/HypnoScript.CLI.Tests/TestData/valid.hyp +++ /dev/null @@ -1 +0,0 @@ -Focus { induce x: number = 5; } Relax diff --git a/HypnoScript.CLI.Tests/UnitTest1.cs b/HypnoScript.CLI.Tests/UnitTest1.cs deleted file mode 100644 index e280e1f..0000000 --- a/HypnoScript.CLI.Tests/UnitTest1.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System; -using System.IO; -using Xunit; -using HypnoScript.CLI.Commands; - -public class LintCommandIntegrationTests -{ - [Fact] - public void LintCommand_ValidScript_ReturnsZero() - { - // Arrange: Nutze ein valides Skript aus TestData - var scriptPath = Path.Combine("TestData", "valid.hyp"); - // Act - int exitCode = LintCommand.Execute(scriptPath, debug: false, verbose: false); - // Assert - Assert.Equal(0, exitCode); - } - - [Fact] - public void LintCommand_InvalidScript_ReturnsError() - { - // Arrange: Nutze ein fehlerhaftes Skript aus TestData - var scriptPath = Path.Combine("TestData", "invalid.hyp"); - // Act - int exitCode = LintCommand.Execute(scriptPath, debug: false, verbose: false); - // Assert - Assert.Equal(1, exitCode); - } - - [Fact] - public void BenchmarkCommand_ValidScript_ReturnsZero() - { - var scriptPath = Path.Combine("TestData", "valid.hyp"); - int exitCode = HypnoScript.CLI.Commands.BenchmarkCommand.Execute(scriptPath, debug: false, verbose: false); - Assert.Equal(0, exitCode); - } - - [Fact] - public void ProfileCommand_ValidScript_ReturnsZero() - { - var scriptPath = Path.Combine("TestData", "valid.hyp"); - int exitCode = HypnoScript.CLI.Commands.ProfileCommand.Execute(scriptPath, debug: false, verbose: false); - Assert.Equal(0, exitCode); - } - - [Fact] - public void OptimizeCommand_ValidScript_ReturnsZero() - { - var scriptPath = Path.Combine("TestData", "valid.hyp"); - int exitCode = HypnoScript.CLI.Commands.OptimizeCommand.Execute(scriptPath, debug: false, verbose: false); - Assert.Equal(0, exitCode); - } -} diff --git a/HypnoScript.CLI/AppLogger.cs b/HypnoScript.CLI/AppLogger.cs deleted file mode 100644 index 7354f44..0000000 --- a/HypnoScript.CLI/AppLogger.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System; -using Microsoft.Extensions.Logging; - -namespace HypnoScript.CLI -{ - public static class AppLogger - { - private static ILogger? _logger; - - public static void Configure(ILogger logger) - { - _logger = logger; - } - - public static void Info(string message) - { - if (_logger != null) - _logger.LogInformation(message); - else - Console.WriteLine($"[INFO] {message}"); - } - - public static void Warn(string message) - { - if (_logger != null) - _logger.LogWarning(message); - else - Console.WriteLine($"[WARN] {message}"); - } - - public static void Error(string message, Exception? ex = null) - { - if (_logger != null) - _logger.LogError(ex, message); - else - { - Console.ForegroundColor = ConsoleColor.Red; - Console.Error.WriteLine($"[ERROR] {message}"); - if (ex != null) - { - Console.Error.WriteLine($" {ex.GetType().Name}: {ex.Message}"); - Console.Error.WriteLine(ex.StackTrace); - } - Console.ResetColor(); - } - } - - public static void Debug(string message) - { - if (_logger != null) - _logger.LogDebug(message); - else - Console.WriteLine($"[DEBUG] {message}"); - } - } -} diff --git a/HypnoScript.CLI/Commands/AnalyzeCommand.cs b/HypnoScript.CLI/Commands/AnalyzeCommand.cs deleted file mode 100644 index 26cbe7f..0000000 --- a/HypnoScript.CLI/Commands/AnalyzeCommand.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using HypnoScript.LexerParser.Lexer; -using HypnoScript.LexerParser.Parser; -using HypnoScript.CLI; - -namespace HypnoScript.CLI.Commands -{ - public static class AnalyzeCommand - { - public static int Execute(string filePath, bool debug, bool verbose) - { - AppLogger.Info("=== ANALYZE MODE ==="); - - if (!File.Exists(filePath)) - { - AppLogger.Error($"File not found: {filePath}"); - return 2; - } - - try - { - if (debug) AppLogger.Debug($"Reading file: {filePath}"); - var source = File.ReadAllText(filePath); - if (debug) AppLogger.Debug($"File read, length: {source.Length}"); - - var lexer = new HypnoLexer(source); - var tokens = lexer.Lex().ToList(); - var parser = new HypnoParser(tokens); - var program = parser.ParseProgram(); - - AppLogger.Info("📊 Analysis Results:"); - AppLogger.Info($" File size: {source.Length} characters"); - AppLogger.Info($" Lines of code: {source.Split('\n').Length}"); - AppLogger.Info($" Tokens: {tokens.Count}"); - AppLogger.Info($" Statements: {program.Statements.Count}"); - - if (verbose) - { - AppLogger.Info("\n🔍 Detailed Analysis:"); - var tokenTypes = tokens.GroupBy(t => t.Type).OrderByDescending(g => g.Count()); - foreach (var group in tokenTypes) - { - AppLogger.Info($" {group.Key}: {group.Count()}"); - } - } - - return 0; - } - catch (Exception ex) - { - AppLogger.Error($"Analysis failed for {filePath}", ex); - return 1; - } - } - } -} diff --git a/HypnoScript.CLI/Commands/ApiCommand.cs b/HypnoScript.CLI/Commands/ApiCommand.cs deleted file mode 100644 index 5e2fa0f..0000000 --- a/HypnoScript.CLI/Commands/ApiCommand.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; -using System.IO; -using HypnoScript.CLI; - -namespace HypnoScript.CLI.Commands -{ - public static class ApiCommand - { - public static int Execute(string filePath, bool debug, bool verbose) - { - AppLogger.Info("=== API SERVER MODE ==="); - AppLogger.Info("🔌 Starting HypnoScript API Server..."); - - if (!File.Exists(filePath)) - { - AppLogger.Error($"File not found: {filePath}"); - return 2; - } - - try - { - AppLogger.Info("🔗 API server features:"); - AppLogger.Info(" - RESTful API endpoints"); - AppLogger.Info(" - JSON request/response handling"); - AppLogger.Info(" - Authentication & authorization"); - AppLogger.Info(" - Rate limiting"); - AppLogger.Info(" - CORS support"); - AppLogger.Info(" - Request/response logging"); - AppLogger.Info(" - Health check endpoints"); - AppLogger.Info(" - Metrics collection"); - - AppLogger.Info("\n🌐 Server would start on: http://localhost:5000"); - AppLogger.Info("📚 Swagger UI: http://localhost:5000/swagger"); - AppLogger.Info("💚 Health check: http://localhost:5000/health"); - AppLogger.Info("📊 Metrics: http://localhost:5000/metrics"); - - AppLogger.Warn("\n⚠️ API server is not yet fully implemented."); - AppLogger.Info(" This is a placeholder for the Runtime Edition feature."); - - return 0; - } - catch (Exception ex) - { - AppLogger.Error($"API server failed for {filePath}", ex); - return 1; - } - } - } -} diff --git a/HypnoScript.CLI/Commands/BenchmarkCommand.cs b/HypnoScript.CLI/Commands/BenchmarkCommand.cs deleted file mode 100644 index 99d29f6..0000000 --- a/HypnoScript.CLI/Commands/BenchmarkCommand.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System; -using System.IO; -using HypnoScript.CLI; -using HypnoScript.LexerParser.Lexer; -using HypnoScript.LexerParser.Parser; -using HypnoScript.Compiler.Interpreter; -using System.Diagnostics; - -namespace HypnoScript.CLI.Commands -{ - public static class BenchmarkCommand - { - public static int Execute(string filePath, bool debug, bool verbose) - { - AppLogger.Info("=== BENCHMARK MODE ==="); - if (!File.Exists(filePath)) - { - AppLogger.Error($"File not found: {filePath}"); - return 1; - } - string source = File.ReadAllText(filePath); - try - { - var lexer = new HypnoLexer(source); - var tokens = lexer.Lex().ToList(); - var parser = new HypnoParser(tokens); - var program = parser.ParseProgram(); - var interpreter = new HypnoInterpreter(); - var sw = Stopwatch.StartNew(); - interpreter.ExecuteProgram(program); - sw.Stop(); - AppLogger.Info($"Execution time: {sw.ElapsedMilliseconds} ms"); - return 0; - } - catch (Exception ex) - { - AppLogger.Error($"Benchmark error: {ex.Message}"); - if (debug) - AppLogger.Error(ex.StackTrace ?? "No stacktrace available."); - return 1; - } - } - } -} diff --git a/HypnoScript.CLI/Commands/CompileCommand.cs b/HypnoScript.CLI/Commands/CompileCommand.cs deleted file mode 100644 index cb062a2..0000000 --- a/HypnoScript.CLI/Commands/CompileCommand.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using HypnoScript.LexerParser.Lexer; -using HypnoScript.LexerParser.Parser; -using HypnoScript.Compiler.Analysis; -using HypnoScript.Compiler.CodeGen; -using HypnoScript.CLI; - -namespace HypnoScript.CLI.Commands -{ - public static class CompileCommand - { - public static int Execute(string filePath, bool debug, bool verbose) - { - AppLogger.Info("=== COMPILE MODE ==="); - - if (!File.Exists(filePath)) - { - AppLogger.Error($"File not found: {filePath}"); - return 2; - } - - try - { - if (debug) AppLogger.Debug($"Reading file: {filePath}"); - var source = File.ReadAllText(filePath); - if (debug) AppLogger.Debug($"File read, length: {source.Length}"); - - var lexer = new HypnoLexer(source); - var tokens = lexer.Lex().ToList(); - var parser = new HypnoParser(tokens); - var program = parser.ParseProgram(); - - var typeChecker = new TypeChecker(); - typeChecker.Check(program); - - var outputPath = Path.ChangeExtension(filePath, ".wat"); - var codeGen = new WasmCodeGenerator(); - var wasmCode = codeGen.Generate(program); - - File.WriteAllText(outputPath, wasmCode); - AppLogger.Info($"✓ Compiled to: {outputPath}"); - - if (verbose) - { - AppLogger.Info($"📄 Generated {wasmCode.Length} characters of WASM code"); - } - - return 0; - } - catch (Exception ex) - { - AppLogger.Error($"Compilation failed for {filePath}", ex); - return 1; - } - } - } -} diff --git a/HypnoScript.CLI/Commands/ConfigCommand.cs b/HypnoScript.CLI/Commands/ConfigCommand.cs deleted file mode 100644 index 99b4e88..0000000 --- a/HypnoScript.CLI/Commands/ConfigCommand.cs +++ /dev/null @@ -1,446 +0,0 @@ -using System; -using System.CommandLine; -using HypnoScript.CLI; -using HypnoScript.Core.Configuration; - -namespace HypnoScript.CLI.Commands -{ - /// - /// Command for managing HypnoScript configuration. - /// - public static class ConfigCommand - { - /// - /// Executes the configuration command. - /// - /// Show current configuration - /// Reset configuration to defaults - /// Set a configuration value - /// Get a configuration value - /// Export configuration to file - /// Import configuration from file - public static void Execute(bool show, bool reset, string? set, string? get, string? export, string? import) - { - try - { - var config = AppConfiguration.Instance; - - if (show) - { - ShowConfiguration(config); - } - else if (reset) - { - config.ResetToDefaults(); - AppLogger.Info("Configuration reset to defaults."); - } - else if (!string.IsNullOrEmpty(set)) - { - SetConfigurationValue(config, set); - } - else if (!string.IsNullOrEmpty(get)) - { - GetConfigurationValue(config, get); - } - else if (!string.IsNullOrEmpty(export)) - { - ExportConfiguration(config, export); - } - else if (!string.IsNullOrEmpty(import)) - { - ImportConfiguration(config, import); - } - else - { - ShowConfiguration(config); - } - } - catch (Exception ex) - { - AppLogger.Error($"Configuration operation failed: {ex.Message}", ex); - Environment.Exit(1); - } - } - - private static void ShowConfiguration(AppConfiguration config) - { - AppLogger.Info("=== HypnoScript Configuration ==="); - - AppLogger.Info("\n--- CLI Settings ---"); - AppLogger.Info($"Default Timeout: {config.Cli.DefaultTimeout}ms"); - AppLogger.Info($"Max Concurrent Operations: {config.Cli.MaxConcurrentOperations}"); - AppLogger.Info($"Verbose Output: {config.Cli.VerboseOutput}"); - AppLogger.Info($"Colored Output: {config.Cli.ColoredOutput}"); - AppLogger.Info($"Default Output Format: {config.Cli.DefaultOutputFormat}"); - AppLogger.Info($"Enable Auto-completion: {config.Cli.EnableAutoCompletion}"); - AppLogger.Info($"History File: {config.Cli.HistoryFilePath}"); - AppLogger.Info($"Max History Entries: {config.Cli.MaxHistoryEntries}"); - - AppLogger.Info("\n--- Runtime Settings ---"); - AppLogger.Info($"Max Execution Time: {config.Runtime.MaxExecutionTime}ms"); - AppLogger.Info($"Max Memory Usage: {config.Runtime.MaxMemoryUsage}MB"); - AppLogger.Info($"Enable Garbage Collection: {config.Runtime.EnableGarbageCollection}"); - AppLogger.Info($"GC Interval: {config.Runtime.GarbageCollectionInterval}ms"); - AppLogger.Info($"Enable Stack Trace: {config.Runtime.EnableStackTrace}"); - AppLogger.Info($"Max Stack Depth: {config.Runtime.MaxStackDepth}"); - AppLogger.Info($"Enable Builtin Caching: {config.Runtime.EnableBuiltinCaching}"); - AppLogger.Info($"Builtin Cache Size: {config.Runtime.BuiltinCacheSize}"); - AppLogger.Info($"Enable Type Checking: {config.Runtime.EnableTypeChecking}"); - AppLogger.Info($"Strict Mode: {config.Runtime.StrictMode}"); - - AppLogger.Info("\n--- Logging Settings ---"); - AppLogger.Info($"Log Level: {config.Logging.LogLevel}"); - AppLogger.Info($"Enable File Logging: {config.Logging.EnableFileLogging}"); - AppLogger.Info($"Log File Path: {config.Logging.LogFilePath}"); - AppLogger.Info($"Max Log File Size: {config.Logging.MaxLogFileSize}MB"); - AppLogger.Info($"Max Log Files: {config.Logging.MaxLogFiles}"); - AppLogger.Info($"Enable Console Logging: {config.Logging.EnableConsoleLogging}"); - AppLogger.Info($"Include Timestamps: {config.Logging.IncludeTimestamps}"); - AppLogger.Info($"Include Thread Info: {config.Logging.IncludeThreadInfo}"); - - AppLogger.Info("\n--- Development Settings ---"); - AppLogger.Info($"Debug Mode: {config.Development.DebugMode}"); - AppLogger.Info($"Enable Profiling: {config.Development.EnableProfiling}"); - AppLogger.Info($"Detailed Error Reporting: {config.Development.DetailedErrorReporting}"); - AppLogger.Info($"Enable Source Maps: {config.Development.EnableSourceMaps}"); - AppLogger.Info($"Enable Hot Reload: {config.Development.EnableHotReload}"); - AppLogger.Info($"Enable Experimental Features: {config.Development.EnableExperimentalFeatures}"); - AppLogger.Info($"Development Server Port: {config.Development.DevelopmentServerPort}"); - AppLogger.Info($"Enable Remote Debugging: {config.Development.EnableRemoteDebugging}"); - AppLogger.Info($"Remote Debugging Port: {config.Development.RemoteDebuggingPort}"); - } - - private static void SetConfigurationValue(AppConfiguration config, string setValue) - { - var parts = setValue.Split('=', 2); - if (parts.Length != 2) - { - AppLogger.Error("Invalid format. Use: section.key=value"); - return; - } - - var keyPath = parts[0]; - var value = parts[1]; - - if (SetConfigValue(config, keyPath, value)) - { - config.SaveConfiguration(); - AppLogger.Info($"Configuration value '{keyPath}' set to '{value}'"); - } - else - { - AppLogger.Error($"Failed to set configuration value '{keyPath}'"); - } - } - - private static void GetConfigurationValue(AppConfiguration config, string keyPath) - { - var value = GetConfigValue(config, keyPath); - if (value != null) - { - AppLogger.Info($"{keyPath} = {value}"); - } - else - { - AppLogger.Error($"Configuration key '{keyPath}' not found"); - } - } - - private static void ExportConfiguration(AppConfiguration config, string filePath) - { - try - { - config.SaveConfiguration(); - AppLogger.Info($"Configuration exported to: {filePath}"); - } - catch (Exception ex) - { - AppLogger.Error($"Failed to export configuration: {ex.Message}"); - } - } - - private static void ImportConfiguration(AppConfiguration config, string filePath) - { - try - { - config.LoadConfiguration(); - AppLogger.Info($"Configuration imported from: {filePath}"); - } - catch (Exception ex) - { - AppLogger.Error($"Failed to import configuration: {ex.Message}"); - } - } - - private static bool SetConfigValue(AppConfiguration config, string keyPath, string value) - { - var parts = keyPath.Split('.'); - if (parts.Length != 2) - { - return false; - } - - var section = parts[0].ToLower(); - var key = parts[1]; - - try - { - switch (section) - { - case "cli": - return SetCliValue(config.Cli, key, value); - case "runtime": - return SetRuntimeValue(config.Runtime, key, value); - case "logging": - return SetLoggingValue(config.Logging, key, value); - case "development": - return SetDevelopmentValue(config.Development, key, value); - default: - return false; - } - } - catch - { - return false; - } - } - - private static object? GetConfigValue(AppConfiguration config, string keyPath) - { - var parts = keyPath.Split('.'); - if (parts.Length != 2) - { - return null; - } - - var section = parts[0].ToLower(); - var key = parts[1]; - - switch (section) - { - case "cli": - return GetCliValue(config.Cli, key); - case "runtime": - return GetRuntimeValue(config.Runtime, key); - case "logging": - return GetLoggingValue(config.Logging, key); - case "development": - return GetDevelopmentValue(config.Development, key); - default: - return null; - } - } - - private static bool SetCliValue(CliSettings cli, string key, string value) - { - switch (key.ToLower()) - { - case "defaulttimeout": - cli.DefaultTimeout = int.Parse(value); - return true; - case "maxconcurrentoperations": - cli.MaxConcurrentOperations = int.Parse(value); - return true; - case "verboseoutput": - cli.VerboseOutput = bool.Parse(value); - return true; - case "coloredoutput": - cli.ColoredOutput = bool.Parse(value); - return true; - case "defaultoutputformat": - cli.DefaultOutputFormat = value; - return true; - case "enableautocompletion": - cli.EnableAutoCompletion = bool.Parse(value); - return true; - case "historyfilepath": - cli.HistoryFilePath = value; - return true; - case "maxhistoryentries": - cli.MaxHistoryEntries = int.Parse(value); - return true; - default: - return false; - } - } - - private static object? GetCliValue(CliSettings cli, string key) - { - return key.ToLower() switch - { - "defaulttimeout" => cli.DefaultTimeout, - "maxconcurrentoperations" => cli.MaxConcurrentOperations, - "verboseoutput" => cli.VerboseOutput, - "coloredoutput" => cli.ColoredOutput, - "defaultoutputformat" => cli.DefaultOutputFormat, - "enableautocompletion" => cli.EnableAutoCompletion, - "historyfilepath" => cli.HistoryFilePath, - "maxhistoryentries" => cli.MaxHistoryEntries, - _ => null - }; - } - - private static bool SetRuntimeValue(RuntimeSettings runtime, string key, string value) - { - switch (key.ToLower()) - { - case "maxexecutiontime": - runtime.MaxExecutionTime = int.Parse(value); - return true; - case "maxmemoryusage": - runtime.MaxMemoryUsage = int.Parse(value); - return true; - case "enablegarbagecollection": - runtime.EnableGarbageCollection = bool.Parse(value); - return true; - case "garbagecollectioninterval": - runtime.GarbageCollectionInterval = int.Parse(value); - return true; - case "enablestacktrace": - runtime.EnableStackTrace = bool.Parse(value); - return true; - case "maxstackdepth": - runtime.MaxStackDepth = int.Parse(value); - return true; - case "enablebuiltincaching": - runtime.EnableBuiltinCaching = bool.Parse(value); - return true; - case "builtincachesize": - runtime.BuiltinCacheSize = int.Parse(value); - return true; - case "enabletypechecking": - runtime.EnableTypeChecking = bool.Parse(value); - return true; - case "strictmode": - runtime.StrictMode = bool.Parse(value); - return true; - default: - return false; - } - } - - private static object? GetRuntimeValue(RuntimeSettings runtime, string key) - { - return key.ToLower() switch - { - "maxexecutiontime" => runtime.MaxExecutionTime, - "maxmemoryusage" => runtime.MaxMemoryUsage, - "enablegarbagecollection" => runtime.EnableGarbageCollection, - "garbagecollectioninterval" => runtime.GarbageCollectionInterval, - "enablestacktrace" => runtime.EnableStackTrace, - "maxstackdepth" => runtime.MaxStackDepth, - "enablebuiltincaching" => runtime.EnableBuiltinCaching, - "builtincachesize" => runtime.BuiltinCacheSize, - "enabletypechecking" => runtime.EnableTypeChecking, - "strictmode" => runtime.StrictMode, - _ => null - }; - } - - private static bool SetLoggingValue(LoggingSettings logging, string key, string value) - { - switch (key.ToLower()) - { - case "loglevel": - logging.LogLevel = value; - return true; - case "enablefilelogging": - logging.EnableFileLogging = bool.Parse(value); - return true; - case "logfilepath": - logging.LogFilePath = value; - return true; - case "maxlogfilesize": - logging.MaxLogFileSize = int.Parse(value); - return true; - case "maxlogfiles": - logging.MaxLogFiles = int.Parse(value); - return true; - case "enableconsolelogging": - logging.EnableConsoleLogging = bool.Parse(value); - return true; - case "includetimestamps": - logging.IncludeTimestamps = bool.Parse(value); - return true; - case "includethreadinfo": - logging.IncludeThreadInfo = bool.Parse(value); - return true; - case "logformat": - logging.LogFormat = value; - return true; - default: - return false; - } - } - - private static object? GetLoggingValue(LoggingSettings logging, string key) - { - return key.ToLower() switch - { - "loglevel" => logging.LogLevel, - "enablefilelogging" => logging.EnableFileLogging, - "logfilepath" => logging.LogFilePath, - "maxlogfilesize" => logging.MaxLogFileSize, - "maxlogfiles" => logging.MaxLogFiles, - "enableconsolelogging" => logging.EnableConsoleLogging, - "includetimestamps" => logging.IncludeTimestamps, - "includethreadinfo" => logging.IncludeThreadInfo, - "logformat" => logging.LogFormat, - _ => null - }; - } - - private static bool SetDevelopmentValue(DevelopmentSettings development, string key, string value) - { - switch (key.ToLower()) - { - case "debugmode": - development.DebugMode = bool.Parse(value); - return true; - case "enableprofiling": - development.EnableProfiling = bool.Parse(value); - return true; - case "detailederrorreporting": - development.DetailedErrorReporting = bool.Parse(value); - return true; - case "enablesourcemaps": - development.EnableSourceMaps = bool.Parse(value); - return true; - case "enablehotreload": - development.EnableHotReload = bool.Parse(value); - return true; - case "enableexperimentalfeatures": - development.EnableExperimentalFeatures = bool.Parse(value); - return true; - case "developmentserverport": - development.DevelopmentServerPort = int.Parse(value); - return true; - case "enableremotedebugging": - development.EnableRemoteDebugging = bool.Parse(value); - return true; - case "remotedebuggingport": - development.RemoteDebuggingPort = int.Parse(value); - return true; - default: - return false; - } - } - - private static object? GetDevelopmentValue(DevelopmentSettings development, string key) - { - return key.ToLower() switch - { - "debugmode" => development.DebugMode, - "enableprofiling" => development.EnableProfiling, - "detailederrorreporting" => development.DetailedErrorReporting, - "enablesourcemaps" => development.EnableSourceMaps, - "enablehotreload" => development.EnableHotReload, - "enableexperimentalfeatures" => development.EnableExperimentalFeatures, - "developmentserverport" => development.DevelopmentServerPort, - "enableremotedebugging" => development.EnableRemoteDebugging, - "remotedebuggingport" => development.RemoteDebuggingPort, - _ => null - }; - } - } -} diff --git a/HypnoScript.CLI/Commands/DeployCommand.cs b/HypnoScript.CLI/Commands/DeployCommand.cs deleted file mode 100644 index c735c36..0000000 --- a/HypnoScript.CLI/Commands/DeployCommand.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; -using System.IO; -using HypnoScript.CLI; - -namespace HypnoScript.CLI.Commands -{ - public static class DeployCommand - { - public static int Execute(string filePath, bool debug, bool verbose) - { - AppLogger.Info("=== DEPLOY MODE ==="); - AppLogger.Info("☁️ Deploying HypnoScript Application..."); - - if (!File.Exists(filePath)) - { - AppLogger.Error($"File not found: {filePath}"); - return 2; - } - - try - { - AppLogger.Info("🚀 Deployment features:"); - AppLogger.Info(" - Multi-cloud support (AWS, Azure, GCP)"); - AppLogger.Info(" - Container deployment (Docker)"); - AppLogger.Info(" - Kubernetes orchestration"); - AppLogger.Info(" - CI/CD pipeline integration"); - AppLogger.Info(" - Environment-specific configurations"); - AppLogger.Info(" - Blue-green deployment"); - AppLogger.Info(" - Rollback capabilities"); - AppLogger.Info(" - Infrastructure as Code (Terraform)"); - - AppLogger.Info("\n☁️ Supported platforms:"); - AppLogger.Info(" - AWS Lambda / ECS / EC2"); - AppLogger.Info(" - Azure Functions / AKS / VM"); - AppLogger.Info(" - Google Cloud Functions / GKE / Compute"); - AppLogger.Info(" - Docker containers"); - AppLogger.Info(" - Kubernetes clusters"); - - AppLogger.Warn("\n⚠️ Deployment is not yet fully implemented."); - AppLogger.Info(" This is a placeholder for the Runtime Edition feature."); - - return 0; - } - catch (Exception ex) - { - AppLogger.Error($"Deployment failed for {filePath}", ex); - return 1; - } - } - } -} diff --git a/HypnoScript.CLI/Commands/DocsCommand.cs b/HypnoScript.CLI/Commands/DocsCommand.cs deleted file mode 100644 index 9133009..0000000 --- a/HypnoScript.CLI/Commands/DocsCommand.cs +++ /dev/null @@ -1,540 +0,0 @@ -using System; -using System.IO; -using System.Text; -using System.Collections.Generic; -using System.Linq; -using HypnoScript.CLI; -using HypnoScript.LexerParser.Lexer; -using HypnoScript.LexerParser.Parser; -using HypnoScript.LexerParser.AST; - -namespace HypnoScript.CLI.Commands -{ - public static class DocsCommand - { - public static int Execute(string filePath, bool debug, bool verbose) - { - AppLogger.Info("=== DOCS MODE ==="); - AppLogger.Info("📚 Generating HypnoScript Documentation..."); - - if (!File.Exists(filePath)) - { - AppLogger.Error($"File not found: {filePath}"); - return 2; - } - - try - { - // Datei parsen - string source = File.ReadAllText(filePath); - var lexer = new HypnoLexer(source); - var tokens = lexer.Lex().ToList(); - var parser = new HypnoParser(tokens); - var program = parser.ParseProgram(); - - // Dokumentation generieren - var documentation = GenerateDocumentation(program, filePath, debug, verbose); - - // Ausgabedateien erstellen - var outputDir = Path.Combine(Path.GetDirectoryName(filePath) ?? ".", "docs"); - Directory.CreateDirectory(outputDir); - - // HTML-Dokumentation - var htmlDoc = GenerateHtmlDocumentation(documentation); - var htmlPath = Path.Combine(outputDir, Path.GetFileNameWithoutExtension(filePath) + "_docs.html"); - File.WriteAllText(htmlPath, htmlDoc, Encoding.UTF8); - - // Markdown-Dokumentation - var markdownDoc = GenerateMarkdownDocumentation(documentation); - var markdownPath = Path.Combine(outputDir, Path.GetFileNameWithoutExtension(filePath) + "_docs.md"); - File.WriteAllText(markdownPath, markdownDoc, Encoding.UTF8); - - // JSON-Dokumentation - var jsonDoc = GenerateJsonDocumentation(documentation); - var jsonPath = Path.Combine(outputDir, Path.GetFileNameWithoutExtension(filePath) + "_docs.json"); - File.WriteAllText(jsonPath, jsonDoc, Encoding.UTF8); - - AppLogger.Info("✅ Documentation generated successfully!"); - AppLogger.Info($"📄 HTML: {htmlPath}"); - AppLogger.Info($"📄 Markdown: {markdownPath}"); - AppLogger.Info($"📄 JSON: {jsonPath}"); - - if (verbose) - { - AppLogger.Info("\n📊 Documentation Summary:"); - AppLogger.Info($" - Functions: {documentation.Functions.Count}"); - AppLogger.Info($" - Variables: {documentation.Variables.Count}"); - AppLogger.Info($" - Sessions: {documentation.Sessions.Count}"); - AppLogger.Info($" - Tranceifies: {documentation.Tranceifies.Count}"); - AppLogger.Info($" - Lines of Code: {documentation.LinesOfCode}"); - } - - return 0; - } - catch (Exception ex) - { - AppLogger.Error($"Documentation generation failed for {filePath}", ex); - return 1; - } - } - - private static DocumentationData GenerateDocumentation(ProgramNode program, string filePath, bool debug, bool verbose) - { - var doc = new DocumentationData - { - FileName = Path.GetFileName(filePath), - FilePath = filePath, - GeneratedAt = DateTime.Now, - LinesOfCode = File.ReadAllLines(filePath).Length - }; - - // Analysiere alle Statements - foreach (var stmt in program.Statements) - { - AnalyzeStatement(stmt, doc, debug); - } - - return doc; - } - - private static void AnalyzeStatement(IStatement stmt, DocumentationData doc, bool debug) - { - switch (stmt) - { - case FunctionDeclNode func: - doc.Functions.Add(new FunctionDoc - { - Name = func.Name, - ReturnType = func.ReturnType ?? "unknown", - Parameters = func.Parameters.Select(p => new ParameterDoc - { - Name = p.Name, - Type = p.TypeName ?? "unknown" - }).ToList(), - LineNumber = 0 // TODO: Implement line tracking - }); - break; - - case VarDeclNode varDecl: - doc.Variables.Add(new VariableDoc - { - Name = varDecl.Identifier, - Type = varDecl.TypeName ?? "inferred", - IsExternal = varDecl.FromExternal, - LineNumber = 0 - }); - break; - - case SessionDeclNode session: - doc.Sessions.Add(new SessionDoc - { - Name = session.Name, - Members = session.Members.Select(m => new MemberDoc - { - Name = GetMemberName(m), - Type = GetMemberType(m), - Visibility = GetMemberVisibility(m) - }).ToList(), - LineNumber = 0 - }); - break; - - case TranceifyDeclNode tranceify: - doc.Tranceifies.Add(new TranceifyDoc - { - Name = tranceify.Name, - Members = tranceify.Members.Select(m => new MemberDoc - { - Name = GetMemberName(m), - Type = GetMemberType(m), - Visibility = "public" - }).ToList(), - LineNumber = 0 - }); - break; - - case MindLinkNode mindLink: - doc.Imports.Add(new ImportDoc - { - FileName = mindLink.FileName, - LineNumber = 0 - }); - break; - - default: - if (debug) - { - AppLogger.Debug($"Unhandled statement type: {stmt.GetType().Name}"); - } - break; - } - } - - private static string GetMemberName(SessionMemberNode member) - { - if (member.Declaration is VarDeclNode varDecl) - return varDecl.Identifier; - if (member.Declaration is FunctionDeclNode funcDecl) - return funcDecl.Name; - return "unknown"; - } - - private static string GetMemberType(SessionMemberNode member) - { - if (member.Declaration is VarDeclNode varDecl) - return varDecl.TypeName ?? "inferred"; - if (member.Declaration is FunctionDeclNode funcDecl) - return funcDecl.ReturnType ?? "void"; - return "unknown"; - } - - private static string GetMemberVisibility(SessionMemberNode member) - { - return member.IsExposed ? "public" : "private"; - } - - private static string GetMemberName(VarDeclNode varDecl) - { - return varDecl.Identifier; - } - - private static string GetMemberType(VarDeclNode varDecl) - { - return varDecl.TypeName ?? "inferred"; - } - - private static string GenerateHtmlDocumentation(DocumentationData doc) - { - var html = new StringBuilder(); - html.AppendLine(""); - html.AppendLine(""); - html.AppendLine(""); - html.AppendLine(" "); - html.AppendLine(" "); - html.AppendLine($" HypnoScript Documentation - {doc.FileName}"); - html.AppendLine(" "); - html.AppendLine(""); - html.AppendLine(""); - - // Header - html.AppendLine("
"); - html.AppendLine($"

HypnoScript Documentation

"); - html.AppendLine($"

File: {doc.FileName}

"); - html.AppendLine($"

Generated: {doc.GeneratedAt:yyyy-MM-dd HH:mm:ss}

"); - html.AppendLine("
"); - - // Statistics - html.AppendLine("
"); - html.AppendLine($"
{doc.Functions.Count}
Functions
"); - html.AppendLine($"
{doc.Variables.Count}
Variables
"); - html.AppendLine($"
{doc.Sessions.Count}
Sessions
"); - html.AppendLine($"
{doc.Tranceifies.Count}
Tranceifies
"); - html.AppendLine($"
{doc.LinesOfCode}
Lines of Code
"); - html.AppendLine("
"); - - // Functions - if (doc.Functions.Any()) - { - html.AppendLine("
"); - html.AppendLine("

Functions

"); - foreach (var func in doc.Functions) - { - html.AppendLine("
"); - html.AppendLine($"
{func.Name}
"); - html.AppendLine($"
Returns: {func.ReturnType}
"); - if (func.Parameters.Any()) - { - html.AppendLine("
Parameters:
"); - foreach (var param in func.Parameters) - { - html.AppendLine($" {param.Name}: {param.Type}"); - } - } - html.AppendLine("
"); - } - html.AppendLine("
"); - } - - // Variables - if (doc.Variables.Any()) - { - html.AppendLine("
"); - html.AppendLine("

Variables

"); - foreach (var var in doc.Variables) - { - html.AppendLine("
"); - html.AppendLine($"
{var.Name}
"); - html.AppendLine($"
Type: {var.Type}
"); - if (var.IsExternal) - { - html.AppendLine("
External input
"); - } - html.AppendLine("
"); - } - html.AppendLine("
"); - } - - // Sessions - if (doc.Sessions.Any()) - { - html.AppendLine("
"); - html.AppendLine("

Sessions

"); - foreach (var session in doc.Sessions) - { - html.AppendLine("
"); - html.AppendLine($"
{session.Name}
"); - if (session.Members.Any()) - { - html.AppendLine("
Members:
"); - foreach (var member in session.Members) - { - html.AppendLine($"
{member.Visibility} {member.Name}: {member.Type}
"); - } - } - html.AppendLine("
"); - } - html.AppendLine("
"); - } - - // Tranceifies - if (doc.Tranceifies.Any()) - { - html.AppendLine("
"); - html.AppendLine("

Tranceifies

"); - foreach (var tranceify in doc.Tranceifies) - { - html.AppendLine("
"); - html.AppendLine($"
{tranceify.Name}
"); - if (tranceify.Members.Any()) - { - html.AppendLine("
Members:
"); - foreach (var member in tranceify.Members) - { - html.AppendLine($"
{member.Name}: {member.Type}
"); - } - } - html.AppendLine("
"); - } - html.AppendLine("
"); - } - - // Imports - if (doc.Imports.Any()) - { - html.AppendLine("
"); - html.AppendLine("

Imports

"); - foreach (var import in doc.Imports) - { - html.AppendLine($"
{import.FileName}
"); - } - html.AppendLine("
"); - } - - html.AppendLine(""); - html.AppendLine(""); - - return html.ToString(); - } - - private static string GenerateMarkdownDocumentation(DocumentationData doc) - { - var markdown = new StringBuilder(); - - // Header - markdown.AppendLine($"# HypnoScript Documentation - {doc.FileName}"); - markdown.AppendLine(); - markdown.AppendLine($"**Generated:** {doc.GeneratedAt:yyyy-MM-dd HH:mm:ss}"); - markdown.AppendLine($"**Lines of Code:** {doc.LinesOfCode}"); - markdown.AppendLine(); - - // Statistics - markdown.AppendLine("## Statistics"); - markdown.AppendLine(); - markdown.AppendLine($"- **Functions:** {doc.Functions.Count}"); - markdown.AppendLine($"- **Variables:** {doc.Variables.Count}"); - markdown.AppendLine($"- **Sessions:** {doc.Sessions.Count}"); - markdown.AppendLine($"- **Tranceifies:** {doc.Tranceifies.Count}"); - markdown.AppendLine($"- **Imports:** {doc.Imports.Count}"); - markdown.AppendLine(); - - // Functions - if (doc.Functions.Any()) - { - markdown.AppendLine("## Functions"); - markdown.AppendLine(); - foreach (var func in doc.Functions) - { - markdown.AppendLine($"### {func.Name}"); - markdown.AppendLine(); - markdown.AppendLine($"**Returns:** `{func.ReturnType}`"); - if (func.Parameters.Any()) - { - markdown.AppendLine(); - markdown.AppendLine("**Parameters:**"); - foreach (var param in func.Parameters) - { - markdown.AppendLine($"- `{param.Name}`: `{param.Type}`"); - } - } - markdown.AppendLine(); - } - } - - // Variables - if (doc.Variables.Any()) - { - markdown.AppendLine("## Variables"); - markdown.AppendLine(); - foreach (var var in doc.Variables) - { - markdown.AppendLine($"### {var.Name}"); - markdown.AppendLine(); - markdown.AppendLine($"**Type:** `{var.Type}`"); - if (var.IsExternal) - { - markdown.AppendLine("**External Input:** Yes"); - } - markdown.AppendLine(); - } - } - - // Sessions - if (doc.Sessions.Any()) - { - markdown.AppendLine("## Sessions"); - markdown.AppendLine(); - foreach (var session in doc.Sessions) - { - markdown.AppendLine($"### {session.Name}"); - markdown.AppendLine(); - if (session.Members.Any()) - { - markdown.AppendLine("**Members:**"); - foreach (var member in session.Members) - { - markdown.AppendLine($"- `{member.Visibility} {member.Name}: {member.Type}`"); - } - } - markdown.AppendLine(); - } - } - - // Tranceifies - if (doc.Tranceifies.Any()) - { - markdown.AppendLine("## Tranceifies"); - markdown.AppendLine(); - foreach (var tranceify in doc.Tranceifies) - { - markdown.AppendLine($"### {tranceify.Name}"); - markdown.AppendLine(); - if (tranceify.Members.Any()) - { - markdown.AppendLine("**Members:**"); - foreach (var member in tranceify.Members) - { - markdown.AppendLine($"- `{member.Name}: {member.Type}`"); - } - } - markdown.AppendLine(); - } - } - - // Imports - if (doc.Imports.Any()) - { - markdown.AppendLine("## Imports"); - markdown.AppendLine(); - foreach (var import in doc.Imports) - { - markdown.AppendLine($"- `{import.FileName}`"); - } - markdown.AppendLine(); - } - - return markdown.ToString(); - } - - private static string GenerateJsonDocumentation(DocumentationData doc) - { - return System.Text.Json.JsonSerializer.Serialize(doc, new System.Text.Json.JsonSerializerOptions - { - WriteIndented = true - }); - } - } - - // Documentation data classes - public class DocumentationData - { - public string FileName { get; set; } = ""; - public string FilePath { get; set; } = ""; - public DateTime GeneratedAt { get; set; } - public int LinesOfCode { get; set; } - public List Functions { get; set; } = new(); - public List Variables { get; set; } = new(); - public List Sessions { get; set; } = new(); - public List Tranceifies { get; set; } = new(); - public List Imports { get; set; } = new(); - } - - public class FunctionDoc - { - public string Name { get; set; } = ""; - public string ReturnType { get; set; } = ""; - public List Parameters { get; set; } = new(); - public int LineNumber { get; set; } - } - - public class ParameterDoc - { - public string Name { get; set; } = ""; - public string Type { get; set; } = ""; - } - - public class VariableDoc - { - public string Name { get; set; } = ""; - public string Type { get; set; } = ""; - public bool IsExternal { get; set; } - public int LineNumber { get; set; } - } - - public class SessionDoc - { - public string Name { get; set; } = ""; - public List Members { get; set; } = new(); - public int LineNumber { get; set; } - } - - public class TranceifyDoc - { - public string Name { get; set; } = ""; - public List Members { get; set; } = new(); - public int LineNumber { get; set; } - } - - public class MemberDoc - { - public string Name { get; set; } = ""; - public string Type { get; set; } = ""; - public string Visibility { get; set; } = "public"; - } - - public class ImportDoc - { - public string FileName { get; set; } = ""; - public int LineNumber { get; set; } - } -} diff --git a/HypnoScript.CLI/Commands/FormatCommand.cs b/HypnoScript.CLI/Commands/FormatCommand.cs deleted file mode 100644 index 1486599..0000000 --- a/HypnoScript.CLI/Commands/FormatCommand.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; -using System.IO; -using HypnoScript.CLI; - -namespace HypnoScript.CLI.Commands -{ - public static class FormatCommand - { - public static int Execute(string filePath, bool debug, bool verbose) - { - AppLogger.Info("=== FORMAT MODE ==="); - - if (!File.Exists(filePath)) - { - AppLogger.Error($"File not found: {filePath}"); - return 2; - } - - try - { - if (debug) AppLogger.Debug($"Reading file: {filePath}"); - var source = File.ReadAllText(filePath); - if (debug) AppLogger.Debug($"File read, length: {source.Length}"); - // Simple formatting - in a real implementation, this would be more sophisticated - var formatted = source.Replace("\r\n", "\n").Replace("\r", "\n"); - File.WriteAllText(filePath, formatted); - - AppLogger.Info("✓ File formatted successfully!"); - return 0; - } - catch (Exception ex) - { - AppLogger.Error($"Formatting failed for {filePath}", ex); - return 1; - } - } - } -} diff --git a/HypnoScript.CLI/Commands/InfoCommand.cs b/HypnoScript.CLI/Commands/InfoCommand.cs deleted file mode 100644 index 42231e3..0000000 --- a/HypnoScript.CLI/Commands/InfoCommand.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using System.IO; -using HypnoScript.CLI; - -namespace HypnoScript.CLI.Commands -{ - public static class InfoCommand - { - public static int Execute(string filePath, bool debug, bool verbose) - { - AppLogger.Info("=== FILE INFO MODE ==="); - - if (!File.Exists(filePath)) - { - AppLogger.Error($"File not found: {filePath}"); - return 2; - } - - try - { - var fileInfo = new FileInfo(filePath); - AppLogger.Info("📁 File Information:"); - AppLogger.Info($" Name: {fileInfo.Name}"); - AppLogger.Info($" Size: {fileInfo.Length} bytes"); - AppLogger.Info($" Created: {fileInfo.CreationTime}"); - AppLogger.Info($" Modified: {fileInfo.LastWriteTime}"); - AppLogger.Info($" Extension: {fileInfo.Extension}"); - - if (verbose) - { - var source = File.ReadAllText(filePath); - AppLogger.Info($" Lines: {source.Split('\n').Length}"); - AppLogger.Info($" Characters: {source.Length}"); - } - - return 0; - } - catch (Exception ex) - { - AppLogger.Error($"Failed to get file info for {filePath}", ex); - return 1; - } - } - } -} diff --git a/HypnoScript.CLI/Commands/LintCommand.cs b/HypnoScript.CLI/Commands/LintCommand.cs deleted file mode 100644 index e507541..0000000 --- a/HypnoScript.CLI/Commands/LintCommand.cs +++ /dev/null @@ -1,394 +0,0 @@ -using System; -using System.IO; -using System.Collections.Generic; -using System.Linq; -using HypnoScript.CLI; -using HypnoScript.LexerParser.Lexer; -using HypnoScript.LexerParser.Parser; -using HypnoScript.LexerParser.AST; -using HypnoScript.Compiler.Analysis; - -namespace HypnoScript.CLI.Commands -{ - public static class LintCommand - { - public static int Execute(string filePath, bool debug, bool verbose) - { - AppLogger.Info("=== LINT MODE ==="); - - if (!File.Exists(filePath)) - { - AppLogger.Error($"File not found: {filePath}"); - return 1; - } - - string source = File.ReadAllText(filePath); - try - { - var lintResults = new LintResults(); - - // Tokenisierung - var lexer = new HypnoLexer(source); - var tokens = lexer.Lex().ToList(); - if (tokens.Count == 0) - { - AppLogger.Warn("No tokens found. File may be empty or invalid."); - return 1; - } - - if (verbose) - { - foreach (var token in tokens) - { - AppLogger.Debug($"Token: {token.Type} '{token.Lexeme}' @ {token.Line}:{token.Column}"); - } - } - - // Parsing - var parser = new HypnoParser(tokens); - var program = parser.ParseProgram(); - - // Erweiterte Linting-Analyse - PerformLintingAnalysis(program, source, lintResults, verbose); - - // Ergebnisse ausgeben - ReportLintResults(lintResults, verbose); - - if (lintResults.Errors.Count > 0) - { - AppLogger.Error($"Found {lintResults.Errors.Count} errors and {lintResults.Warnings.Count} warnings."); - return 1; - } - else if (lintResults.Warnings.Count > 0) - { - AppLogger.Warn($"Found {lintResults.Warnings.Count} warnings."); - return 0; - } - else - { - AppLogger.Info("No linting issues found."); - return 0; - } - } - catch (Exception ex) - { - AppLogger.Error($"Linting error: {ex.Message}"); - if (debug) - { - AppLogger.Error(ex.StackTrace ?? "No stacktrace available."); - } - return 1; - } - } - - private static void PerformLintingAnalysis(ProgramNode program, string source, LintResults results, bool verbose) - { - var lines = source.Split('\n'); - - // Syntax-Analyse - AnalyzeSyntax(program, results); - - // Stil-Analyse - AnalyzeStyle(program, lines, results); - - // Performance-Analyse - AnalyzePerformance(program, results); - - // Sicherheits-Analyse - AnalyzeSecurity(program, results); - - // Best Practices - AnalyzeBestPractices(program, results); - } - - private static void AnalyzeSyntax(ProgramNode program, LintResults results) - { - // Prüfe auf Focus/Relax-Struktur - bool hasFocus = false; - - foreach (var stmt in program.Statements) - { - if (stmt is EntranceBlockNode) - { - hasFocus = true; - } - } - - if (!hasFocus) - { - results.Warnings.Add(new LintIssue - { - Type = LintIssueType.Warning, - Message = "Program should have an entrance block", - Line = 1, - Column = 1, - Code = "LINT001" - }); - } - } - - private static void AnalyzeStyle(ProgramNode program, string[] lines, LintResults results) - { - // Prüfe Zeilenlänge - for (int i = 0; i < lines.Length; i++) - { - if (lines[i].Length > 120) - { - results.Warnings.Add(new LintIssue - { - Type = LintIssueType.Warning, - Message = "Line is too long (>120 characters)", - Line = i + 1, - Column = 1, - Code = "LINT002" - }); - } - } - - // Prüfe Einrückung - for (int i = 0; i < lines.Length; i++) - { - var line = lines[i]; - if (line.Trim().Length > 0 && !line.StartsWith(" ") && !line.StartsWith("\t")) - { - // Erste Zeile und spezielle Zeilen ausnehmen - if (i > 0 && !line.Trim().StartsWith("Focus") && !line.Trim().StartsWith("Relax")) - { - results.Warnings.Add(new LintIssue - { - Type = LintIssueType.Warning, - Message = "Inconsistent indentation", - Line = i + 1, - Column = 1, - Code = "LINT003" - }); - } - } - } - } - - private static void AnalyzePerformance(ProgramNode program, LintResults results) - { - int loopCount = 0; - int functionCount = 0; - - void CountStatements(IStatement stmt) - { - switch (stmt) - { - case WhileStatementNode: - case LoopStatementNode: - loopCount++; - break; - case FunctionDeclNode: - functionCount++; - break; - case BlockStatementNode block: - foreach (var s in block.Statements) CountStatements(s); - break; - case EntranceBlockNode entrance: - foreach (var s in entrance.Statements) CountStatements(s); - break; - case IfStatementNode ifStmt: - foreach (var s in ifStmt.ThenBranch) CountStatements(s); - if (ifStmt.ElseBranch != null) - foreach (var s in ifStmt.ElseBranch) CountStatements(s); - break; - } - } - - foreach (var stmt in program.Statements) CountStatements(stmt); - - if (loopCount > 5) - { - results.Warnings.Add(new LintIssue - { - Type = LintIssueType.Warning, - Message = $"Too many loops ({loopCount}). Consider optimizing.", - Line = 1, - Column = 1, - Code = "LINT004" - }); - } - - if (functionCount == 0) - { - results.Warnings.Add(new LintIssue - { - Type = LintIssueType.Warning, - Message = "No functions defined. Consider modularizing your code.", - Line = 1, - Column = 1, - Code = "LINT005" - }); - } - } - - private static void AnalyzeSecurity(ProgramNode program, LintResults results) - { - // Prüfe auf potenzielle Sicherheitsprobleme - void CheckSecurity(IStatement stmt) - { - switch (stmt) - { - case VarDeclNode varDecl: - if (varDecl.FromExternal && varDecl.TypeName == "string") - { - results.Warnings.Add(new LintIssue - { - Type = LintIssueType.Warning, - Message = "External string input should be validated", - Line = 1, - Column = 1, - Code = "LINT006" - }); - } - break; - case BlockStatementNode block: - foreach (var s in block.Statements) CheckSecurity(s); - break; - case EntranceBlockNode entrance: - foreach (var s in entrance.Statements) CheckSecurity(s); - break; - case IfStatementNode ifStmt: - foreach (var s in ifStmt.ThenBranch) CheckSecurity(s); - if (ifStmt.ElseBranch != null) - foreach (var s in ifStmt.ElseBranch) CheckSecurity(s); - break; - } - } - - foreach (var stmt in program.Statements) CheckSecurity(stmt); - } - - private static void AnalyzeBestPractices(ProgramNode program, LintResults results) - { - // Prüfe Best Practices - int variableCount = 0; - var variableNames = new HashSet(); - - void CheckBestPractices(IStatement stmt) - { - switch (stmt) - { - case VarDeclNode varDecl: - variableCount++; - if (!variableNames.Add(varDecl.Identifier)) - { - results.Errors.Add(new LintIssue - { - Type = LintIssueType.Error, - Message = $"Variable '{varDecl.Identifier}' is already defined", - Line = 1, - Column = 1, - Code = "LINT007" - }); - } - - // Prüfe Namenskonventionen - if (varDecl.Identifier.Length < 2) - { - results.Warnings.Add(new LintIssue - { - Type = LintIssueType.Warning, - Message = $"Variable name '{varDecl.Identifier}' is too short", - Line = 1, - Column = 1, - Code = "LINT008" - }); - } - break; - case FunctionDeclNode funcDecl: - if (funcDecl.Name.Length < 3) - { - results.Warnings.Add(new LintIssue - { - Type = LintIssueType.Warning, - Message = $"Function name '{funcDecl.Name}' is too short", - Line = 1, - Column = 1, - Code = "LINT009" - }); - } - break; - case BlockStatementNode block: - foreach (var s in block.Statements) CheckBestPractices(s); - break; - case EntranceBlockNode entrance: - foreach (var s in entrance.Statements) CheckBestPractices(s); - break; - case IfStatementNode ifStmt: - foreach (var s in ifStmt.ThenBranch) CheckBestPractices(s); - if (ifStmt.ElseBranch != null) - foreach (var s in ifStmt.ElseBranch) CheckBestPractices(s); - break; - } - } - - foreach (var stmt in program.Statements) CheckBestPractices(stmt); - - if (variableCount > 20) - { - results.Warnings.Add(new LintIssue - { - Type = LintIssueType.Warning, - Message = $"Too many variables ({variableCount}). Consider using records or arrays.", - Line = 1, - Column = 1, - Code = "LINT010" - }); - } - } - - private static void ReportLintResults(LintResults results, bool verbose) - { - if (results.Errors.Count > 0) - { - AppLogger.Info("\n=== ERRORS ==="); - foreach (var error in results.Errors) - { - AppLogger.Error($"[{error.Code}] Line {error.Line}:{error.Column} - {error.Message}"); - } - } - - if (results.Warnings.Count > 0) - { - AppLogger.Info("\n=== WARNINGS ==="); - foreach (var warning in results.Warnings) - { - AppLogger.Warn($"[{warning.Code}] Line {warning.Line}:{warning.Column} - {warning.Message}"); - } - } - - if (verbose) - { - AppLogger.Info("\n=== SUMMARY ==="); - AppLogger.Info($"Errors: {results.Errors.Count}"); - AppLogger.Info($"Warnings: {results.Warnings.Count}"); - AppLogger.Info($"Total Issues: {results.Errors.Count + results.Warnings.Count}"); - } - } - } - - public class LintResults - { - public List Errors { get; set; } = new(); - public List Warnings { get; set; } = new(); - } - - public class LintIssue - { - public LintIssueType Type { get; set; } - public string Message { get; set; } = ""; - public int Line { get; set; } - public int Column { get; set; } - public string Code { get; set; } = ""; - } - - public enum LintIssueType - { - Error, - Warning, - Info - } -} diff --git a/HypnoScript.CLI/Commands/MonitorCommand.cs b/HypnoScript.CLI/Commands/MonitorCommand.cs deleted file mode 100644 index b9c1e06..0000000 --- a/HypnoScript.CLI/Commands/MonitorCommand.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System; -using System.IO; -using HypnoScript.CLI; - -namespace HypnoScript.CLI.Commands -{ - public static class MonitorCommand - { - public static int Execute(string filePath, bool debug, bool verbose) - { - AppLogger.Info("=== MONITOR MODE ==="); - AppLogger.Info("📊 Starting HypnoScript Application Monitor..."); - - if (!File.Exists(filePath)) - { - AppLogger.Error($"File not found: {filePath}"); - return 2; - } - - try - { - AppLogger.Info("📈 Monitoring features:"); - AppLogger.Info(" - Real-time performance metrics"); - AppLogger.Info(" - CPU, memory, and disk usage"); - AppLogger.Info(" - Request/response times"); - AppLogger.Info(" - Error rates and logs"); - AppLogger.Info(" - Custom business metrics"); - AppLogger.Info(" - Alerting and notifications"); - AppLogger.Info(" - Historical data analysis"); - AppLogger.Info(" - Dashboard visualization"); - - AppLogger.Info("\n🔍 Metrics collected:"); - AppLogger.Info(" - Execution time per function"); - AppLogger.Info(" - Memory allocation patterns"); - AppLogger.Info(" - Builtin function usage"); - AppLogger.Info(" - Error frequency and types"); - AppLogger.Info(" - User interaction patterns"); - AppLogger.Info(" - System resource utilization"); - - AppLogger.Warn("\n⚠️ Monitoring is not yet fully implemented."); - AppLogger.Info(" This is a placeholder for the Runtime Edition feature."); - - return 0; - } - catch (Exception ex) - { - AppLogger.Error($"Monitoring failed for {filePath}", ex); - return 1; - } - } - } -} diff --git a/HypnoScript.CLI/Commands/OptimizeCommand.cs b/HypnoScript.CLI/Commands/OptimizeCommand.cs deleted file mode 100644 index 604a10e..0000000 --- a/HypnoScript.CLI/Commands/OptimizeCommand.cs +++ /dev/null @@ -1,545 +0,0 @@ -using System; -using System.IO; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using HypnoScript.CLI; -using HypnoScript.LexerParser.Lexer; -using HypnoScript.LexerParser.Parser; -using HypnoScript.LexerParser.AST; - -namespace HypnoScript.CLI.Commands -{ - public static class OptimizeCommand - { - public static int Execute(string filePath, bool debug, bool verbose) - { - AppLogger.Info("=== OPTIMIZE MODE ==="); - - if (!File.Exists(filePath)) - { - AppLogger.Error($"File not found: {filePath}"); - return 1; - } - - try - { - string source = File.ReadAllText(filePath); - var optimizationResults = new OptimizationResults(); - - // Parse the program - var lexer = new HypnoLexer(source); - var tokens = lexer.Lex().ToList(); - var parser = new HypnoParser(tokens); - var program = parser.ParseProgram(); - - // Perform optimizations - var optimizedSource = PerformOptimizations(program, source, optimizationResults, verbose); - - // Generate optimized file - var outputPath = GenerateOptimizedFile(filePath, optimizedSource); - - // Report results - ReportOptimizationResults(optimizationResults, outputPath, verbose); - - return 0; - } - catch (Exception ex) - { - AppLogger.Error($"Optimization error: {ex.Message}"); - if (debug) - { - AppLogger.Error(ex.StackTrace ?? "No stacktrace available."); - } - return 1; - } - } - - private static string PerformOptimizations(ProgramNode program, string source, OptimizationResults results, bool verbose) - { - var optimizedSource = source; - - // 1. Dead Code Elimination - optimizedSource = EliminateDeadCode(program, optimizedSource, results); - - // 2. Constant Folding - optimizedSource = FoldConstants(program, optimizedSource, results); - - // 3. Loop Optimization - optimizedSource = OptimizeLoops(program, optimizedSource, results); - - // 4. Variable Optimization - optimizedSource = OptimizeVariables(program, optimizedSource, results); - - // 5. Function Inlining - optimizedSource = InlineFunctions(program, optimizedSource, results); - - // 6. Expression Simplification - optimizedSource = SimplifyExpressions(program, optimizedSource, results); - - // 7. Memory Optimization - optimizedSource = OptimizeMemory(program, optimizedSource, results); - - if (verbose) - { - AppLogger.Info($"Original size: {source.Length} characters"); - AppLogger.Info($"Optimized size: {optimizedSource.Length} characters"); - AppLogger.Info($"Size reduction: {((double)(source.Length - optimizedSource.Length) / source.Length * 100):F1}%"); - } - - return optimizedSource; - } - - private static string EliminateDeadCode(ProgramNode program, string source, OptimizationResults results) - { - var lines = source.Split('\n').ToList(); - var deadCodeLines = new List(); - - // Find unreachable code - for (int i = 0; i < lines.Count; i++) - { - var line = lines[i].Trim(); - - // Check for unreachable code after return statements - if (line.StartsWith("return") && i < lines.Count - 1) - { - var nextLine = lines[i + 1].Trim(); - if (nextLine.Length > 0 && !nextLine.StartsWith("}") && !nextLine.StartsWith("else")) - { - deadCodeLines.Add(i + 1); - results.Optimizations.Add(new Optimization - { - Type = OptimizationType.DeadCodeElimination, - Description = "Removed unreachable code after return statement", - Line = i + 2 - }); - } - } - - // Check for unused variables (simplified) - if (line.StartsWith("induce") && line.Contains("=")) - { - var varName = ExtractVariableName(line); - if (!IsVariableUsed(varName, lines, i + 1)) - { - deadCodeLines.Add(i); - results.Optimizations.Add(new Optimization - { - Type = OptimizationType.DeadCodeElimination, - Description = $"Removed unused variable '{varName}'", - Line = i + 1 - }); - } - } - } - - // Remove dead code lines (in reverse order to maintain indices) - for (int i = deadCodeLines.Count - 1; i >= 0; i--) - { - lines.RemoveAt(deadCodeLines[i]); - } - - return string.Join("\n", lines); - } - - private static string FoldConstants(ProgramNode program, string source, OptimizationResults results) - { - var lines = source.Split('\n').ToList(); - - for (int i = 0; i < lines.Count; i++) - { - var line = lines[i]; - var optimizedLine = FoldConstantsInLine(line); - - if (optimizedLine != line) - { - lines[i] = optimizedLine; - results.Optimizations.Add(new Optimization - { - Type = OptimizationType.ConstantFolding, - Description = "Folded constant expressions", - Line = i + 1 - }); - } - } - - return string.Join("\n", lines); - } - - private static string FoldConstantsInLine(string line) - { - // Simple constant folding for arithmetic expressions - if (line.Contains(" + ") && line.Contains("induce")) - { - // Find arithmetic expressions like "induce x = 2 + 3" - var match = System.Text.RegularExpressions.Regex.Match(line, @"induce\s+(\w+)\s*=\s*(\d+)\s*\+\s*(\d+)"); - if (match.Success) - { - var varName = match.Groups[1].Value; - var left = int.Parse(match.Groups[2].Value); - var right = int.Parse(match.Groups[3].Value); - var result = left + right; - - return line.Replace(match.Value, $"induce {varName} = {result}"); - } - } - - return line; - } - - private static string OptimizeLoops(ProgramNode program, string source, OptimizationResults results) - { - var lines = source.Split('\n').ToList(); - - for (int i = 0; i < lines.Count; i++) - { - var line = lines[i].Trim(); - - // Optimize simple loops - if (line.StartsWith("for") && line.Contains("induce i = 0")) - { - // Check if it's a simple counting loop - var nextLines = GetNextLines(lines, i, 5); - if (IsSimpleCountingLoop(nextLines)) - { - results.Optimizations.Add(new Optimization - { - Type = OptimizationType.LoopOptimization, - Description = "Optimized simple counting loop", - Line = i + 1 - }); - } - } - } - - return string.Join("\n", lines); - } - - private static string OptimizeVariables(ProgramNode program, string source, OptimizationResults results) - { - var lines = source.Split('\n').ToList(); - var variableUsage = new Dictionary(); - - // Count variable usage - for (int i = 0; i < lines.Count; i++) - { - var line = lines[i]; - var variables = ExtractVariables(line); - foreach (var var in variables) - { - variableUsage[var] = variableUsage.GetValueOrDefault(var, 0) + 1; - } - } - - // Suggest optimizations for rarely used variables - foreach (var kvp in variableUsage) - { - if (kvp.Value == 1) - { - results.Suggestions.Add(new OptimizationSuggestion - { - Type = SuggestionType.VariableOptimization, - Description = $"Variable '{kvp.Key}' is used only once - consider inlining", - Priority = SuggestionPriority.Low - }); - } - } - - return source; - } - - private static string InlineFunctions(ProgramNode program, string source, OptimizationResults results) - { - // Find small functions that can be inlined - var lines = source.Split('\n').ToList(); - - for (int i = 0; i < lines.Count; i++) - { - var line = lines[i].Trim(); - - if (line.StartsWith("suggestion") && line.Contains("(")) - { - var functionName = ExtractFunctionName(line); - var functionBody = GetFunctionBody(lines, i); - - if (functionBody.Count <= 3) // Small function - { - results.Suggestions.Add(new OptimizationSuggestion - { - Type = SuggestionType.FunctionInlining, - Description = $"Function '{functionName}' is small and could be inlined", - Priority = SuggestionPriority.Medium - }); - } - } - } - - return source; - } - - private static string SimplifyExpressions(ProgramNode program, string source, OptimizationResults results) - { - var lines = source.Split('\n').ToList(); - - for (int i = 0; i < lines.Count; i++) - { - var line = lines[i]; - var simplifiedLine = SimplifyExpression(line); - - if (simplifiedLine != line) - { - lines[i] = simplifiedLine; - results.Optimizations.Add(new Optimization - { - Type = OptimizationType.ExpressionSimplification, - Description = "Simplified expression", - Line = i + 1 - }); - } - } - - return string.Join("\n", lines); - } - - private static string SimplifyExpression(string line) - { - // Simplify common patterns - line = line.Replace(" + 0", ""); - line = line.Replace("0 + ", ""); - line = line.Replace(" * 1", ""); - line = line.Replace("1 * ", ""); - line = line.Replace(" && true", ""); - line = line.Replace("true && ", ""); - line = line.Replace(" || false", ""); - line = line.Replace("false || ", ""); - - return line; - } - - private static string OptimizeMemory(ProgramNode program, string source, OptimizationResults results) - { - var lines = source.Split('\n').ToList(); - - // Check for large arrays that could be optimized - for (int i = 0; i < lines.Count; i++) - { - var line = lines[i].Trim(); - - if (line.Contains("induce") && line.Contains("[")) - { - // Check for large array literals - var arrayMatch = System.Text.RegularExpressions.Regex.Match(line, @"\[\s*([^]]*)\s*\]"); - if (arrayMatch.Success) - { - var arrayContent = arrayMatch.Groups[1].Value; - var elements = arrayContent.Split(',').Length; - - if (elements > 10) - { - results.Suggestions.Add(new OptimizationSuggestion - { - Type = SuggestionType.MemoryOptimization, - Description = $"Large array with {elements} elements - consider lazy loading", - Priority = SuggestionPriority.High - }); - } - } - } - } - - return source; - } - - private static string GenerateOptimizedFile(string originalPath, string optimizedSource) - { - var directory = Path.GetDirectoryName(originalPath); - var fileName = Path.GetFileNameWithoutExtension(originalPath); - var extension = Path.GetExtension(originalPath); - var outputPath = Path.Combine(directory ?? ".", $"{fileName}_optimized{extension}"); - - File.WriteAllText(outputPath, optimizedSource, Encoding.UTF8); - return outputPath; - } - - private static void ReportOptimizationResults(OptimizationResults results, string outputPath, bool verbose) - { - AppLogger.Info($"✅ Optimization completed! Output: {outputPath}"); - - if (results.Optimizations.Count > 0) - { - AppLogger.Info($"\n=== OPTIMIZATIONS APPLIED ({results.Optimizations.Count}) ==="); - foreach (var opt in results.Optimizations) - { - AppLogger.Info($"[{opt.Type}] Line {opt.Line}: {opt.Description}"); - } - } - - if (results.Suggestions.Count > 0) - { - AppLogger.Info($"\n=== OPTIMIZATION SUGGESTIONS ({results.Suggestions.Count}) ==="); - foreach (var suggestion in results.Suggestions.OrderBy(s => s.Priority)) - { - var priorityIcon = suggestion.Priority switch - { - SuggestionPriority.High => "🔴", - SuggestionPriority.Medium => "🟡", - SuggestionPriority.Low => "🟢", - _ => "⚪" - }; - - AppLogger.Info($"{priorityIcon} [{suggestion.Type}] {suggestion.Description}"); - } - } - - if (verbose) - { - AppLogger.Info($"\n=== OPTIMIZATION SUMMARY ==="); - AppLogger.Info($"Applied optimizations: {results.Optimizations.Count}"); - AppLogger.Info($"Suggestions: {results.Suggestions.Count}"); - AppLogger.Info($"High priority suggestions: {results.Suggestions.Count(s => s.Priority == SuggestionPriority.High)}"); - } - } - - // Helper methods - private static string ExtractVariableName(string line) - { - var match = System.Text.RegularExpressions.Regex.Match(line, @"induce\s+(\w+)"); - return match.Success ? match.Groups[1].Value : ""; - } - - private static bool IsVariableUsed(string varName, List lines, int startIndex) - { - for (int i = startIndex; i < lines.Count; i++) - { - if (lines[i].Contains(varName)) - { - return true; - } - } - return false; - } - - private static List GetNextLines(List lines, int startIndex, int count) - { - var result = new List(); - for (int i = startIndex + 1; i < Math.Min(startIndex + 1 + count, lines.Count); i++) - { - result.Add(lines[i]); - } - return result; - } - - private static bool IsSimpleCountingLoop(List lines) - { - return lines.Any(line => line.Contains("induce i = i + 1")); - } - - private static List ExtractVariables(string line) - { - var variables = new List(); - var matches = System.Text.RegularExpressions.Regex.Matches(line, @"\b\w+\b"); - foreach (System.Text.RegularExpressions.Match match in matches) - { - var word = match.Value; - if (!IsKeyword(word)) - { - variables.Add(word); - } - } - return variables; - } - - private static bool IsKeyword(string word) - { - var keywords = new[] { "induce", "observe", "if", "else", "while", "for", "return", "true", "false", "null" }; - return keywords.Contains(word); - } - - private static string ExtractFunctionName(string line) - { - var match = System.Text.RegularExpressions.Regex.Match(line, @"suggestion\s+(\w+)"); - return match.Success ? match.Groups[1].Value : ""; - } - - private static List GetFunctionBody(List lines, int functionStart) - { - var body = new List(); - var braceCount = 0; - var started = false; - - for (int i = functionStart; i < lines.Count; i++) - { - var line = lines[i]; - - if (line.Contains("{")) - { - braceCount++; - started = true; - } - - if (started) - { - body.Add(line); - } - - if (line.Contains("}")) - { - braceCount--; - if (braceCount == 0) - { - break; - } - } - } - - return body; - } - } - - public class OptimizationResults - { - public List Optimizations { get; set; } = new(); - public List Suggestions { get; set; } = new(); - } - - public class Optimization - { - public OptimizationType Type { get; set; } - public string Description { get; set; } = ""; - public int Line { get; set; } - } - - public class OptimizationSuggestion - { - public SuggestionType Type { get; set; } - public string Description { get; set; } = ""; - public SuggestionPriority Priority { get; set; } - } - - public enum OptimizationType - { - DeadCodeElimination, - ConstantFolding, - LoopOptimization, - VariableOptimization, - FunctionInlining, - ExpressionSimplification, - MemoryOptimization - } - - public enum SuggestionType - { - VariableOptimization, - FunctionInlining, - MemoryOptimization, - PerformanceOptimization, - CodeStructure - } - - public enum SuggestionPriority - { - Low, - Medium, - High - } -} diff --git a/HypnoScript.CLI/Commands/ProfileCommand.cs b/HypnoScript.CLI/Commands/ProfileCommand.cs deleted file mode 100644 index 8c5c304..0000000 --- a/HypnoScript.CLI/Commands/ProfileCommand.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System; -using System.IO; -using HypnoScript.CLI; -using HypnoScript.LexerParser.Lexer; -using HypnoScript.LexerParser.Parser; -using HypnoScript.Compiler.Interpreter; -using System.Diagnostics; - -namespace HypnoScript.CLI.Commands -{ - public static class ProfileCommand - { - public static int Execute(string filePath, bool debug, bool verbose) - { - AppLogger.Info("=== PROFILE MODE ==="); - if (!File.Exists(filePath)) - { - AppLogger.Error($"File not found: {filePath}"); - return 1; - } - string source = File.ReadAllText(filePath); - try - { - var lexer = new HypnoLexer(source); - var tokens = lexer.Lex().ToList(); - var parser = new HypnoParser(tokens); - var program = parser.ParseProgram(); - var interpreter = new HypnoInterpreter(); - var process = Process.GetCurrentProcess(); - process.Refresh(); - long memBefore = process.PrivateMemorySize64; - var sw = Stopwatch.StartNew(); - interpreter.ExecuteProgram(program); - sw.Stop(); - process.Refresh(); - long memAfter = process.PrivateMemorySize64; - AppLogger.Info($"Execution time: {sw.ElapsedMilliseconds} ms"); - AppLogger.Info($"Memory usage: {memAfter / 1024} KB (delta: {(memAfter - memBefore) / 1024} KB)"); - return 0; - } - catch (Exception ex) - { - AppLogger.Error($"Profile error: {ex.Message}"); - if (debug) - AppLogger.Error(ex.StackTrace ?? "No stacktrace available."); - return 1; - } - } - } -} diff --git a/HypnoScript.CLI/Commands/RunCommand.cs b/HypnoScript.CLI/Commands/RunCommand.cs deleted file mode 100644 index 9580ea9..0000000 --- a/HypnoScript.CLI/Commands/RunCommand.cs +++ /dev/null @@ -1,109 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using HypnoScript.LexerParser.Lexer; -using HypnoScript.LexerParser.Parser; -using HypnoScript.Compiler.Analysis; -using HypnoScript.Compiler.Interpreter; -using HypnoScript.CLI; - -namespace HypnoScript.CLI.Commands -{ - public static class RunCommand - { - public static int Execute(string filePath, bool debug, bool verbose) - { - AppLogger.Info("=== RUN MODE ==="); - - if (!File.Exists(filePath)) - { - AppLogger.Error($"File not found: {filePath}"); - return 2; - } - - try - { - if (debug) AppLogger.Debug($"Reading file: {filePath}"); - var source = File.ReadAllText(filePath); - if (debug) AppLogger.Debug($"File read, length: {source.Length}"); - - // Syntax validation - if (!source.TrimStart().StartsWith("Focus")) - { - AppLogger.Warn("File doesn't start with 'Focus'"); - return 1; - } - AppLogger.Info("✓ File starts with 'Focus' - syntax OK"); - - // Lexer - if (debug) AppLogger.Debug("Creating lexer..."); - var lexer = new HypnoLexer(source); - var tokens = lexer.Lex().ToList(); - if (debug) AppLogger.Debug($"{tokens.Count} tokens generated"); - AppLogger.Info("✓ Lexing successful!"); - - if (verbose) - { - AppLogger.Info("\n📋 Token Analysis:"); - var tokenTypes = tokens.GroupBy(t => t.Type).OrderByDescending(g => g.Count()); - foreach (var group in tokenTypes.Take(10)) - { - AppLogger.Info($" {group.Key}: {group.Count()} tokens"); - } - } - - // Parser - if (debug) AppLogger.Debug("Creating parser..."); - var parser = new HypnoParser(tokens); - var program = parser.ParseProgram(); - if (debug) AppLogger.Debug($"AST with {program.Statements.Count} statements created"); - AppLogger.Info("✓ Parsing successful!"); - - if (verbose) - { - AppLogger.Info("\n🌳 AST Analysis:"); - var statementTypes = program.Statements.GroupBy(s => s.GetType().Name).OrderByDescending(g => g.Count()); - foreach (var group in statementTypes.Take(5)) - { - AppLogger.Info($" {group.Key}: {group.Count()} statements"); - } - } - - // Type Checker - if (debug) AppLogger.Debug("Running type checker..."); - var typeChecker = new TypeChecker(); - typeChecker.Check(program); - AppLogger.Info("✓ Type checking successful!"); - - // Interpreter - if (debug) AppLogger.Debug("Starting interpreter..."); - var interpreter = new HypnoInterpreter(); - var startTime = DateTime.Now; - interpreter.ExecuteProgram(program); - var endTime = DateTime.Now; - var executionTime = (endTime - startTime).TotalMilliseconds; - - var assertionFailures = interpreter.GetAssertionFailures(); - if (assertionFailures.Count > 0) - { - AppLogger.Error($"{assertionFailures.Count} assertion(s) failed in {filePath}:"); - foreach (var fail in assertionFailures) - { - AppLogger.Error($" - {fail}"); - } - return 1; - } - - AppLogger.Info("✓ Execution completed!"); - AppLogger.Info($"⏱️ Execution time: {executionTime:F2}ms"); - - return 0; - } - catch (Exception ex) - { - AppLogger.Error($"Execution failed for {filePath}", ex); - return 1; - } - } - } -} diff --git a/HypnoScript.CLI/Commands/TestCommand.cs b/HypnoScript.CLI/Commands/TestCommand.cs deleted file mode 100644 index 8c67029..0000000 --- a/HypnoScript.CLI/Commands/TestCommand.cs +++ /dev/null @@ -1,114 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using System.Collections.Generic; -using HypnoScript.CLI; - -namespace HypnoScript.CLI.Commands -{ - public static class TestCommand - { - public static int Execute(string filePath, bool debug, bool verbose) - { - AppLogger.Info("=== TEST MODE ==="); - AppLogger.Info("🧪 Running HypnoScript Tests..."); - - List testFiles; - if (string.IsNullOrEmpty(filePath)) - { - // Alle .hyp-Dateien im Projektverzeichnis rekursiv finden - testFiles = Directory.GetFiles(Directory.GetCurrentDirectory(), "*.hyp", SearchOption.AllDirectories) - .OrderBy(f => f).ToList(); - } - else - { - if (!File.Exists(filePath)) - { - AppLogger.Error($"File not found: {filePath}"); - return 2; - } - testFiles = new List { filePath }; - } - - if (testFiles.Count == 0) - { - AppLogger.Warn("[WARN] No .hyp test files found."); - return 0; - } - - int passed = 0, failed = 0; - var results = new List<(string file, bool ok, TimeSpan duration, string? error)>(); - - foreach (var testFile in testFiles) - { - var sw = System.Diagnostics.Stopwatch.StartNew(); - try - { - int exitCode = RunSingleTest(testFile, debug, verbose); - sw.Stop(); - if (exitCode == 0) - { - results.Add((testFile, true, sw.Elapsed, null)); - passed++; - } - else - { - results.Add((testFile, false, sw.Elapsed, $"Exit code: {exitCode}")); - failed++; - } - } - catch (Exception ex) - { - sw.Stop(); - string errorMessage = ex.Message; - bool isAssertionFailure = errorMessage.Contains("Assertion failed") || errorMessage.StartsWith("Assertion failed"); - - if (isAssertionFailure) - { - // Assertion-Fehler speziell hervorheben - errorMessage = $"ASSERTION FAILED: {errorMessage}"; - } - - results.Add((testFile, false, sw.Elapsed, errorMessage)); - failed++; - } - } - - // Testreport - AppLogger.Info("\n=== Test Results ==="); - foreach (var (file, ok, duration, error) in results) - { - if (ok) - { - AppLogger.Info($"[OK] {System.IO.Path.GetFileName(file),-30} ({duration.TotalMilliseconds:F0} ms)"); - } - else - { - if (error?.Contains("ASSERTION FAILED") == true) - { - AppLogger.Error($"[ASSERT] {System.IO.Path.GetFileName(file),-30} ({duration.TotalMilliseconds:F0} ms)"); - AppLogger.Error($" └─ {error}"); - } - else - { - AppLogger.Error($"[FAIL] {System.IO.Path.GetFileName(file),-30} ({duration.TotalMilliseconds:F0} ms) {error}"); - } - } - } - - AppLogger.Info($"\nSummary: {passed} passed, {failed} failed, {testFiles.Count} total"); - if (failed > 0) - { - AppLogger.Warn($"⚠️ {failed} test(s) failed. Check the output above for details."); - } - - return failed == 0 ? 0 : 1; - } - - private static int RunSingleTest(string filePath, bool debug, bool verbose) - { - // Die Run-Logik aus RunCommand wiederverwenden - return RunCommand.Execute(filePath, debug, verbose); - } - } -} diff --git a/HypnoScript.CLI/Commands/ValidateCommand.cs b/HypnoScript.CLI/Commands/ValidateCommand.cs deleted file mode 100644 index 4ca036b..0000000 --- a/HypnoScript.CLI/Commands/ValidateCommand.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using HypnoScript.LexerParser.Lexer; -using HypnoScript.LexerParser.Parser; -using HypnoScript.Compiler.Analysis; -using HypnoScript.CLI; - -namespace HypnoScript.CLI.Commands -{ - public static class ValidateCommand - { - public static int Execute(string filePath, bool debug, bool verbose) - { - AppLogger.Info("=== VALIDATE MODE ==="); - - if (!File.Exists(filePath)) - { - AppLogger.Error($"File not found: {filePath}"); - return 2; - } - - try - { - if (debug) AppLogger.Debug($"Reading file: {filePath}"); - var source = File.ReadAllText(filePath); - if (debug) AppLogger.Debug($"File read, length: {source.Length}"); - - var lexer = new HypnoLexer(source); - var tokens = lexer.Lex().ToList(); - var parser = new HypnoParser(tokens); - var program = parser.ParseProgram(); - - var typeChecker = new TypeChecker(); - typeChecker.Check(program); - - AppLogger.Info("✓ Validation successful!"); - AppLogger.Info(" ✓ Syntax: OK"); - AppLogger.Info(" ✓ Semantics: OK"); - AppLogger.Info(" ✓ Types: OK"); - - return 0; - } - catch (Exception ex) - { - AppLogger.Error($"Validation failed for {filePath}", ex); - return 1; - } - } - } -} diff --git a/HypnoScript.CLI/Commands/WebCommand.cs b/HypnoScript.CLI/Commands/WebCommand.cs deleted file mode 100644 index 2aaa63e..0000000 --- a/HypnoScript.CLI/Commands/WebCommand.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System; -using System.IO; - -namespace HypnoScript.CLI.Commands -{ - public static class WebCommand - { - public static int Execute(string filePath, bool debug, bool verbose) - { - Console.WriteLine("=== WEB SERVER MODE ==="); - Console.WriteLine("🚀 Starting HypnoScript Web Server..."); - - if (!File.Exists(filePath)) - { - Console.Error.WriteLine($"[ERROR] File not found: {filePath}"); - return 2; - } - - try - { - Console.WriteLine("📡 Web server features:"); - Console.WriteLine(" - Real-time code compilation"); - Console.WriteLine(" - Live code execution"); - Console.WriteLine(" - Interactive development environment"); - Console.WriteLine(" - WebSocket support for real-time updates"); - Console.WriteLine(" - REST API endpoints"); - Console.WriteLine(" - File upload/download"); - Console.WriteLine(" - Session management"); - Console.WriteLine(" - Performance monitoring"); - - Console.WriteLine("\n🌐 Server would start on: http://localhost:8080"); - Console.WriteLine("📊 Dashboard: http://localhost:8080/dashboard"); - Console.WriteLine("🔧 API Docs: http://localhost:8080/api/docs"); - - Console.WriteLine("\n⚠️ Web server is not yet fully implemented."); - Console.WriteLine(" This is a placeholder for the Runtime Edition feature."); - - return 0; - } - catch (Exception ex) - { - Console.Error.WriteLine($"[ERROR] Web server failed: {ex.Message}"); - if (debug) Console.Error.WriteLine(ex.StackTrace); - return 1; - } - } - } -} diff --git a/HypnoScript.CLI/HypnoScript.CLI.csproj b/HypnoScript.CLI/HypnoScript.CLI.csproj deleted file mode 100644 index a1e01c2..0000000 --- a/HypnoScript.CLI/HypnoScript.CLI.csproj +++ /dev/null @@ -1,20 +0,0 @@ - - - - Exe - net8.0 - enable - enable - - - - - - - - - - - - - diff --git a/HypnoScript.CLI/Program.cs b/HypnoScript.CLI/Program.cs deleted file mode 100644 index 5c9da5b..0000000 --- a/HypnoScript.CLI/Program.cs +++ /dev/null @@ -1,258 +0,0 @@ -using System; -using System.IO; -using System.Diagnostics; -using System.Threading.Tasks; -using HypnoScript.LexerParser.Lexer; -using HypnoScript.LexerParser.Parser; -using HypnoScript.Compiler.Analysis; -using HypnoScript.Compiler.Interpreter; -using HypnoScript.Compiler.CodeGen; -using HypnoScript.LexerParser.AST; -using System.Linq; -using System.Collections.Generic; -using System.CommandLine; -using System.CommandLine.Invocation; -using Microsoft.Extensions.Logging; - -namespace HypnoScript.CLI -{ - public class Program - { - public static int Main(string[] args) - { - using var loggerFactory = LoggerFactory.Create(builder => - { - builder.AddSimpleConsole(options => - { - options.SingleLine = true; - options.TimestampFormat = "HH:mm:ss "; - }); - builder.SetMinimumLevel(LogLevel.Information); - }); - var logger = loggerFactory.CreateLogger("HypnoScriptCLI"); - AppLogger.Configure(logger); - - var rootCommand = new RootCommand("HypnoScript CLI - Runtime Edition v1.0.0"); - - var runFileArg = new Argument("file", "The HypnoScript file to execute"); - var runDebugOpt = new Option("--debug", "Enable debug output"); - var runVerboseOpt = new Option("--verbose", "Enable verbose output"); - var runCommand = new Command("run", "Execute HypnoScript code") { runFileArg, runDebugOpt, runVerboseOpt }; - runCommand.SetHandler((string file, bool debug, bool verbose) => - Commands.RunCommand.Execute(file, debug, verbose), runFileArg, runDebugOpt, runVerboseOpt); - rootCommand.AddCommand(runCommand); - - var compileFileArg = new Argument("file", "The HypnoScript file to compile"); - var compileDebugOpt = new Option("--debug", "Enable debug output"); - var compileVerboseOpt = new Option("--verbose", "Enable verbose output"); - var compileCommand = new Command("compile", "Compile to WASM (.wat)") { compileFileArg, compileDebugOpt, compileVerboseOpt }; - compileCommand.SetHandler((string file, bool debug, bool verbose) => - Commands.CompileCommand.Execute(file, debug, verbose), compileFileArg, compileDebugOpt, compileVerboseOpt); - rootCommand.AddCommand(compileCommand); - - var analyzeFileArg = new Argument("file", "The HypnoScript file to analyze"); - var analyzeDebugOpt = new Option("--debug", "Enable debug output"); - var analyzeVerboseOpt = new Option("--verbose", "Enable verbose output"); - var analyzeCommand = new Command("analyze", "Static analysis") { analyzeFileArg, analyzeDebugOpt, analyzeVerboseOpt }; - analyzeCommand.SetHandler((string file, bool debug, bool verbose) => - Commands.AnalyzeCommand.Execute(file, debug, verbose), analyzeFileArg, analyzeDebugOpt, analyzeVerboseOpt); - rootCommand.AddCommand(analyzeCommand); - - var validateFileArg = new Argument("file", "The HypnoScript file to validate"); - var validateDebugOpt = new Option("--debug", "Enable debug output"); - var validateVerboseOpt = new Option("--verbose", "Enable verbose output"); - var validateCommand = new Command("validate", "Validate syntax") { validateFileArg, validateDebugOpt, validateVerboseOpt }; - validateCommand.SetHandler((string file, bool debug, bool verbose) => - Commands.ValidateCommand.Execute(file, debug, verbose), validateFileArg, validateDebugOpt, validateVerboseOpt); - rootCommand.AddCommand(validateCommand); - - var infoFileArg = new Argument("file", "The HypnoScript file to show info for"); - var infoDebugOpt = new Option("--debug", "Enable debug output"); - var infoVerboseOpt = new Option("--verbose", "Enable verbose output"); - var infoCommand = new Command("info", "Show file information") { infoFileArg, infoDebugOpt, infoVerboseOpt }; - infoCommand.SetHandler((string file, bool debug, bool verbose) => - Commands.InfoCommand.Execute(file, debug, verbose), infoFileArg, infoDebugOpt, infoVerboseOpt); - rootCommand.AddCommand(infoCommand); - - var formatFileArg = new Argument("file", "The HypnoScript file to format"); - var formatDebugOpt = new Option("--debug", "Enable debug output"); - var formatVerboseOpt = new Option("--verbose", "Enable verbose output"); - var formatCommand = new Command("format", "Format code") { formatFileArg, formatDebugOpt, formatVerboseOpt }; - formatCommand.SetHandler((string file, bool debug, bool verbose) => - Commands.FormatCommand.Execute(file, debug, verbose), formatFileArg, formatDebugOpt, formatVerboseOpt); - rootCommand.AddCommand(formatCommand); - - var testFileArg = new Argument("file", () => string.Empty, "The HypnoScript file to test (optional, runs all if omitted)"); - var testDebugOpt = new Option("--debug", "Enable debug output"); - var testVerboseOpt = new Option("--verbose", "Enable verbose output"); - var testCommand = new Command("test", "Run tests") { testFileArg, testDebugOpt, testVerboseOpt }; - testCommand.SetHandler((string file, bool debug, bool verbose) => - Commands.TestCommand.Execute(file, debug, verbose), testFileArg, testDebugOpt, testVerboseOpt); - rootCommand.AddCommand(testCommand); - - var docsFileArg = new Argument("file", "The HypnoScript file to generate docs for"); - var docsDebugOpt = new Option("--debug", "Enable debug output"); - var docsVerboseOpt = new Option("--verbose", "Enable verbose output"); - var docsCommand = new Command("docs", "Generate documentation") { docsFileArg, docsDebugOpt, docsVerboseOpt }; - docsCommand.SetHandler((string file, bool debug, bool verbose) => - Commands.DocsCommand.Execute(file, debug, verbose), docsFileArg, docsDebugOpt, docsVerboseOpt); - rootCommand.AddCommand(docsCommand); - - var benchmarkFileArg = new Argument("file", "The HypnoScript file to benchmark"); - var benchmarkDebugOpt = new Option("--debug", "Enable debug output"); - var benchmarkVerboseOpt = new Option("--verbose", "Enable verbose output"); - var benchmarkCommand = new Command("benchmark", "Performance benchmark") { benchmarkFileArg, benchmarkDebugOpt, benchmarkVerboseOpt }; - benchmarkCommand.SetHandler((string file, bool debug, bool verbose) => - Commands.BenchmarkCommand.Execute(file, debug, verbose), benchmarkFileArg, benchmarkDebugOpt, benchmarkVerboseOpt); - rootCommand.AddCommand(benchmarkCommand); - - var profileFileArg = new Argument("file", "The HypnoScript file to profile"); - var profileDebugOpt = new Option("--debug", "Enable debug output"); - var profileVerboseOpt = new Option("--verbose", "Enable verbose output"); - var profileCommand = new Command("profile", "Code profiling") { profileFileArg, profileDebugOpt, profileVerboseOpt }; - profileCommand.SetHandler((string file, bool debug, bool verbose) => - Commands.ProfileCommand.Execute(file, debug, verbose), profileFileArg, profileDebugOpt, profileVerboseOpt); - rootCommand.AddCommand(profileCommand); - - var lintFileArg = new Argument("file", "The HypnoScript file to lint"); - var lintDebugOpt = new Option("--debug", "Enable debug output"); - var lintVerboseOpt = new Option("--verbose", "Enable verbose output"); - var lintCommand = new Command("lint", "Code linting") { lintFileArg, lintDebugOpt, lintVerboseOpt }; - lintCommand.SetHandler((string file, bool debug, bool verbose) => - Commands.LintCommand.Execute(file, debug, verbose), lintFileArg, lintDebugOpt, lintVerboseOpt); - rootCommand.AddCommand(lintCommand); - - var optimizeFileArg = new Argument("file", "The HypnoScript file to optimize"); - var optimizeDebugOpt = new Option("--debug", "Enable debug output"); - var optimizeVerboseOpt = new Option("--verbose", "Enable verbose output"); - var optimizeCommand = new Command("optimize", "Code optimization") { optimizeFileArg, optimizeDebugOpt, optimizeVerboseOpt }; - optimizeCommand.SetHandler((string file, bool debug, bool verbose) => - Commands.OptimizeCommand.Execute(file, debug, verbose), optimizeFileArg, optimizeDebugOpt, optimizeVerboseOpt); - rootCommand.AddCommand(optimizeCommand); - - var webFileArg = new Argument("file", "The HypnoScript file for the web server"); - var webDebugOpt = new Option("--debug", "Enable debug output"); - var webVerboseOpt = new Option("--verbose", "Enable verbose output"); - var webCommand = new Command("web", "Start web server") { webFileArg, webDebugOpt, webVerboseOpt }; - webCommand.SetHandler((string file, bool debug, bool verbose) => - Commands.WebCommand.Execute(file, debug, verbose), webFileArg, webDebugOpt, webVerboseOpt); - rootCommand.AddCommand(webCommand); - - var apiFileArg = new Argument("file", "The HypnoScript file for the API server"); - var apiDebugOpt = new Option("--debug", "Enable debug output"); - var apiVerboseOpt = new Option("--verbose", "Enable verbose output"); - var apiCommand = new Command("api", "Start API server") { apiFileArg, apiDebugOpt, apiVerboseOpt }; - apiCommand.SetHandler((string file, bool debug, bool verbose) => - Commands.ApiCommand.Execute(file, debug, verbose), apiFileArg, apiDebugOpt, apiVerboseOpt); - rootCommand.AddCommand(apiCommand); - - var deployFileArg = new Argument("file", "The HypnoScript file to deploy"); - var deployDebugOpt = new Option("--debug", "Enable debug output"); - var deployVerboseOpt = new Option("--verbose", "Enable verbose output"); - var deployCommand = new Command("deploy", "Deploy application") { deployFileArg, deployDebugOpt, deployVerboseOpt }; - deployCommand.SetHandler((string file, bool debug, bool verbose) => - Commands.DeployCommand.Execute(file, debug, verbose), deployFileArg, deployDebugOpt, deployVerboseOpt); - rootCommand.AddCommand(deployCommand); - - var monitorFileArg = new Argument("file", "The HypnoScript file to monitor"); - var monitorDebugOpt = new Option("--debug", "Enable debug output"); - var monitorVerboseOpt = new Option("--verbose", "Enable verbose output"); - var monitorCommand = new Command("monitor", "Monitor application") { monitorFileArg, monitorDebugOpt, monitorVerboseOpt }; - monitorCommand.SetHandler((string file, bool debug, bool verbose) => - Commands.MonitorCommand.Execute(file, debug, verbose), monitorFileArg, monitorDebugOpt, monitorVerboseOpt); - rootCommand.AddCommand(monitorCommand); - - var configShowOpt = new Option("--show", "Show current configuration"); - var configResetOpt = new Option("--reset", "Reset configuration to defaults"); - var configSetOpt = new Option("--set", "Set a configuration value (format: section.key=value)"); - var configGetOpt = new Option("--get", "Get a configuration value (format: section.key)"); - var configExportOpt = new Option("--export", "Export configuration to file"); - var configImportOpt = new Option("--import", "Import configuration from file"); - var configCommand = new Command("config", "Manage configuration") { configShowOpt, configResetOpt, configSetOpt, configGetOpt, configExportOpt, configImportOpt }; - configCommand.SetHandler((bool show, bool reset, string? set, string? get, string? export, string? import) => - Commands.ConfigCommand.Execute(show, reset, set, get, export, import), configShowOpt, configResetOpt, configSetOpt, configGetOpt, configExportOpt, configImportOpt); - rootCommand.AddCommand(configCommand); - - var versionCommand = new Command("version", "Show version"); - versionCommand.SetHandler(() => ShowVersion()); - rootCommand.AddCommand(versionCommand); - - var helpCommand = new Command("help", "Show help"); - helpCommand.SetHandler(() => ShowUsage()); - rootCommand.AddCommand(helpCommand); - - return rootCommand.Invoke(args); - } - - private static void ShowUsage() - { - Console.WriteLine("HypnoScript CLI - Runtime Edition v1.0.0"); - Console.WriteLine("Usage:"); - Console.WriteLine(" dotnet run -- run [--debug] [--verbose] - Execute HypnoScript code"); - Console.WriteLine(" dotnet run -- compile [--debug] [--verbose] - Compile to WASM (.wat)"); - Console.WriteLine(" dotnet run -- analyze [--debug] [--verbose] - Static analysis"); - Console.WriteLine(" dotnet run -- info [--debug] [--verbose] - Show file information"); - Console.WriteLine(" dotnet run -- validate [--debug] [--verbose] - Validate syntax"); - Console.WriteLine(" dotnet run -- format [--debug] [--verbose] - Format code"); - Console.WriteLine(" dotnet run -- benchmark [--debug] [--verbose] - Performance benchmark"); - Console.WriteLine(" dotnet run -- profile [--debug] [--verbose] - Code profiling"); - Console.WriteLine(" dotnet run -- lint [--debug] [--verbose] - Code linting"); - Console.WriteLine(" dotnet run -- optimize [--debug] [--verbose] - Code optimization"); - Console.WriteLine(" dotnet run -- web [--debug] [--verbose] - Start web server"); - Console.WriteLine(" dotnet run -- api [--debug] [--verbose] - Start API server"); - Console.WriteLine(" dotnet run -- deploy [--debug] [--verbose] - Deploy application"); - Console.WriteLine(" dotnet run -- monitor [--debug] [--verbose] - Monitor application"); - Console.WriteLine(" dotnet run -- test [--debug] [--verbose] - Run tests"); - Console.WriteLine(" dotnet run -- docs [--debug] [--verbose] - Generate documentation"); - Console.WriteLine(" dotnet run -- version - Show version"); - Console.WriteLine(" dotnet run -- help - Show this help"); - Console.WriteLine(); - Console.WriteLine("Runtime Features:"); - Console.WriteLine(" - Web Server with real-time compilation"); - Console.WriteLine(" - REST API Server with automatic routing"); - Console.WriteLine(" - Cloud deployment (AWS, Azure, GCP)"); - Console.WriteLine(" - Application monitoring and metrics"); - Console.WriteLine(" - Automated testing framework"); - Console.WriteLine(" - Documentation generation"); - Console.WriteLine(); - Console.WriteLine("Options:"); - Console.WriteLine(" --debug - Enable debug output"); - Console.WriteLine(" --verbose - Enable verbose output"); - } - - private static void ShowVersion() - { - Console.WriteLine("HypnoScript CLI v1.0.0"); - Console.WriteLine("Runtime Edition with Advanced Features"); - Console.WriteLine("Built with .NET 8.0"); - Console.WriteLine("Features: Lexer, Parser, TypeChecker, Interpreter, WASM CodeGen"); - Console.WriteLine("Runtime: Web Server, API Server, Cloud Deployment, Monitoring"); - } - - public static class CliArgumentValidator - { - public static bool RequireArgs(string[] args, int minCount, string command, out int errorCode) - { - if (args.Length < minCount) - { - Console.WriteLine($"Error: File path required for '{command}' command"); - errorCode = 1; - return false; - } - errorCode = 0; - return true; - } - public static bool RequireFileExists(string filePath, out int errorCode) - { - if (!File.Exists(filePath)) - { - Console.Error.WriteLine($"[ERROR] File not found: {filePath}"); - errorCode = 2; - return false; - } - errorCode = 0; - return true; - } - } - } -} diff --git a/HypnoScript.Compiler.Error/ErrorReporter.cs b/HypnoScript.Compiler.Error/ErrorReporter.cs deleted file mode 100644 index e69de29..0000000 diff --git a/HypnoScript.Compiler.Tests/HypnoScript.Compiler.Tests.csproj b/HypnoScript.Compiler.Tests/HypnoScript.Compiler.Tests.csproj deleted file mode 100644 index aa0bf43..0000000 --- a/HypnoScript.Compiler.Tests/HypnoScript.Compiler.Tests.csproj +++ /dev/null @@ -1,26 +0,0 @@ - - - - net9.0 - enable - enable - false - - - - - - - - - - - - - - - - - - - diff --git a/HypnoScript.Compiler.Tests/TypeCheckerTests.cs b/HypnoScript.Compiler.Tests/TypeCheckerTests.cs deleted file mode 100644 index 03f66c0..0000000 --- a/HypnoScript.Compiler.Tests/TypeCheckerTests.cs +++ /dev/null @@ -1,56 +0,0 @@ -using Xunit; -using HypnoScript.Compiler.Analysis; -using HypnoScript.LexerParser.AST; -using System.Collections.Generic; -using HypnoScript.Compiler.Error; - -namespace HypnoScript.Compiler.Tests -{ - public class TypeCheckerTests - { - [Fact] - public void UnknownType_ShouldReportError() - { - // Arrange: Variable mit unbekanntem Typ - var program = new ProgramNode(new List - { - new VarDeclNode("x", null, new IdentifierExpressionNode("y"), false) - }); - var checker = new TypeChecker(); - ErrorReporter.ClearErrors(); - - // Act - checker.Check(program); - var errors = ErrorReporter.GetErrors(); - - // Debug-Ausgabe aller Fehler - foreach (var err in errors) - { - System.Console.WriteLine($"[TEST-DEBUG] Error: {err}"); - } - // Assert - Assert.Contains(errors, e => e.Contains("could not be inferred (unknown type)")); - } - - [Fact] - public void MindLink_ShouldImportSymbols() - { - // Arrange: MindLink importiert Dummy-Symbole - var program = new ProgramNode(new List - { - new MindLinkNode("dummy.hyp"), - new VarDeclNode("z", "number", new IdentifierExpressionNode("importedVar"), false) - }); - var checker = new TypeChecker(); - ErrorReporter.ClearErrors(); - - // Act - checker.Check(program); - var errors = ErrorReporter.GetErrors(); - - // Assert: Kein Fehler bzgl. 'importedVar' oder unknown - Assert.DoesNotContain(errors, e => e.Contains("importedVar")); - Assert.DoesNotContain(errors, e => e.Contains("unknown")); - } - } -} diff --git a/HypnoScript.Compiler.Tests/UnitTest1.cs b/HypnoScript.Compiler.Tests/UnitTest1.cs deleted file mode 100644 index 4fbacb3..0000000 --- a/HypnoScript.Compiler.Tests/UnitTest1.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace HypnoScript.Compiler.Tests; - -public class UnitTest1 -{ - [Fact] - public void Test1() - { - - } -} diff --git a/HypnoScript.Compiler/Analysis/TypeChecker.cs b/HypnoScript.Compiler/Analysis/TypeChecker.cs deleted file mode 100644 index a65f87f..0000000 --- a/HypnoScript.Compiler/Analysis/TypeChecker.cs +++ /dev/null @@ -1,1075 +0,0 @@ -using System; -using HypnoScript.LexerParser.AST; -using HypnoScript.Core.Types; -using HypnoScript.Compiler.Error; -using System.Collections.Generic; -using HypnoScript.Core.Symbols; -using HypnoScript.LexerParser.Lexer; -using HypnoScript.LexerParser.Parser; -using System.IO; -using System.Linq; - -namespace HypnoScript.Compiler.Analysis -{ - public class TypeChecker - { - private readonly Dictionary _sessions = new(); - private readonly Dictionary _tranceifies = new(); - private readonly SymbolTable _globals = new(); - private HashSet _labelsInScope = new(); - private readonly Dictionary _typeCache = new(); - private readonly List _importedFiles = new(); - - // Runtime-Level: Neben der reinen Traversierung werden Typ-Inkonsistenzen protokolliert. - public void Check(ProgramNode program) - { - // Sammle alle Sessions und tranceify-Definitionen - foreach (var stmt in program.Statements) - { - if (stmt is SessionDeclNode session) - _sessions[session.Name] = session; - if (stmt is TranceifyDeclNode trance) - _tranceifies[trance.Name] = trance; - } - // Check alle Statements - foreach (var stmt in program.Statements) - { - CheckStatement(stmt); - } - } - - private void CheckStatement(IStatement stmt) - { - switch (stmt) - { - case VarDeclNode varDecl: - CheckVarDeclaration(varDecl); - break; - case FunctionDeclNode funcDecl: - CheckFunctionDeclaration(funcDecl); - break; - case SessionDeclNode session: - CheckSessionDeclaration(session); - break; - case SessionMemberNode sessionMember: - CheckSessionMember(sessionMember); - break; - case TranceifyDeclNode trance: - CheckTranceifyDeclaration(trance); - break; - case ExpressionStatementNode exprStmt: - CheckExpression(exprStmt.Expression); - break; - case ObserveStatementNode obs: - CheckExpression(obs.Expression); - break; - case DriftStatementNode drift: - CheckDriftStatement(drift); - break; - case ReturnStatementNode ret: - CheckReturnStatement(ret); - break; - case IfStatementNode ifStmt: - CheckIfStatement(ifStmt); - break; - case WhileStatementNode whileStmt: - CheckWhileStatement(whileStmt); - break; - case LoopStatementNode loopStmt: - CheckLoopStatement(loopStmt); - break; - case SnapStatementNode: - case SinkStatementNode: - // Keine spezielle Typprüfung nötig - break; - case MindLinkNode mindLink: - CheckMindLink(mindLink); - break; - case SharedTranceVarDeclNode shared: - CheckSharedTranceVarDeclaration(shared); - break; - case LabelNode label: - CheckLabelDeclaration(label); - break; - case SinkToNode sinkTo: - CheckSinkToStatement(sinkTo); - break; - case EntranceBlockNode entrance: - CheckEntranceBlock(entrance); - break; - case AssertStatementNode assertStmt: - CheckAssertStatement(assertStmt); - break; - default: - ErrorReporter.ReportWarning($"Unsupported statement type: {stmt.GetType().Name}", 0, 0, "TYPE999"); - break; - } - } - - private void CheckVarDeclaration(VarDeclNode varDecl) - { - var initType = InferExpressionType(varDecl.Initializer); - - // Strengere Typprüfung - if (varDecl.TypeName != null) - { - if (!IsValidType(varDecl.TypeName)) - { - ErrorReporter.Report($"Invalid type '{varDecl.TypeName}' for variable '{varDecl.Identifier}'", 0, 0, "TYPE001"); - return; - } - - if (initType != null && varDecl.TypeName != initType && !IsTypeCompatible(varDecl.TypeName, initType)) - { - ErrorReporter.Report($"Type mismatch: Variable '{varDecl.Identifier}' declared as '{varDecl.TypeName}' but initializer is '{initType}'", 0, 0, "TYPE002"); - } - } - else if (initType == null || initType == "unknown") - { - ErrorReporter.Report($"Type of variable '{varDecl.Identifier}' could not be inferred (unknown type)", 0, 0, "TYPE910"); - } - - if (!_globals.Define(new Symbol(varDecl.Identifier, varDecl.TypeName ?? initType))) - { - ErrorReporter.Report($"Variable '{varDecl.Identifier}' already defined", 0, 0, "TYPE003"); - } - } - - private void CheckFunctionDeclaration(FunctionDeclNode funcDecl) - { - // Prüfe Parameter-Typen - foreach (var param in funcDecl.Parameters) - { - if (!IsValidType(param.TypeName)) - { - ErrorReporter.Report($"Invalid parameter type '{param.TypeName}' in function '{funcDecl.Name}'", 0, 0, "TYPE004"); - } - } - - // Prüfe Return-Typ - if (funcDecl.ReturnType != null && !IsValidType(funcDecl.ReturnType)) - { - ErrorReporter.Report($"Invalid return type '{funcDecl.ReturnType}' for function '{funcDecl.Name}'", 0, 0, "TYPE005"); - } - - // Funktionssymbol anlegen - _globals.Define(new Symbol(funcDecl.Name, funcDecl.ReturnType ?? "unknown")); - - // Prüfe Funktionskörper - foreach (var stmt in funcDecl.Body) - { - CheckStatement(stmt); - } - } - - private void CheckSessionDeclaration(SessionDeclNode session) - { - if (_sessions.ContainsKey(session.Name)) - { - ErrorReporter.Report($"Session '{session.Name}' already defined", 0, 0, "TYPE006"); - return; - } - - // Felder und Methoden prüfen - foreach (var member in session.Members) - { - CheckSessionMember(member); - } - - ValidateSession(session); - } - - private void CheckTranceifyDeclaration(TranceifyDeclNode trance) - { - if (_tranceifies.ContainsKey(trance.Name)) - { - ErrorReporter.Report($"Tranceify '{trance.Name}' already defined", 0, 0, "TYPE007"); - return; - } - - // Felder prüfen - foreach (var member in trance.Members) - { - CheckStatement(member); - } - - ValidateTranceify(trance); - } - - private void CheckDriftStatement(DriftStatementNode drift) - { - var driftType = InferExpressionType(drift.Milliseconds); - if (driftType != "number" && driftType != "int") - { - ErrorReporter.Report($"drift() expects number, got '{driftType}'", 0, 0, "TYPE008"); - } - } - - private void CheckReturnStatement(ReturnStatementNode ret) - { - if (ret.Expression != null) - { - var returnType = InferExpressionType(ret.Expression); - // TODO: Prüfe gegen aktuellen Funktions-Return-Typ - } - CheckExpression(ret.Expression); - } - - private void CheckIfStatement(IfStatementNode ifStmt) - { - var conditionType = InferExpressionType(ifStmt.Condition); - if (conditionType != "boolean") - { - ErrorReporter.Report($"if condition must be boolean, got '{conditionType}'", 0, 0, "TYPE009"); - } - foreach (var s in ifStmt.ThenBranch) - CheckStatement(s); - if (ifStmt.ElseBranch != null) - foreach (var s in ifStmt.ElseBranch) - CheckStatement(s); - } - - private void CheckWhileStatement(WhileStatementNode whileStmt) - { - var whileConditionType = InferExpressionType(whileStmt.Condition); - if (whileConditionType != "boolean") - { - ErrorReporter.Report($"while condition must be boolean, got '{whileConditionType}'", 0, 0, "TYPE010"); - } - foreach (var s in whileStmt.Body) - CheckStatement(s); - } - - private void CheckLoopStatement(LoopStatementNode loopStmt) - { - var loopConditionType = InferExpressionType(loopStmt.Condition); - if (loopConditionType != "boolean") - { - ErrorReporter.Report($"loop condition must be boolean, got '{loopConditionType}'", 0, 0, "TYPE011"); - } - if (loopStmt.Initializer != null) - CheckStatement(loopStmt.Initializer); - if (loopStmt.Iteration != null) - CheckStatement(loopStmt.Iteration); - foreach (var s in loopStmt.Body) - CheckStatement(s); - } - - private void CheckMindLink(MindLinkNode mindLink) - { - // Vollständige Symbolübernahme bei MindLink - if (_importedFiles.Contains(mindLink.FileName)) - { - ErrorReporter.ReportWarning($"File '{mindLink.FileName}' already imported", 0, 0, "TYPE012"); - return; - } - - try - { - if (!File.Exists(mindLink.FileName)) - { - ErrorReporter.Report($"Import file '{mindLink.FileName}' not found", 0, 0, "TYPE013"); - return; - } - - var code = File.ReadAllText(mindLink.FileName); - var lexer = new HypnoLexer(code); - var tokens = lexer.Lex(); - var parser = new HypnoParser(tokens); - var importedProgram = parser.ParseProgram(); - - // Übernehme Sessions - foreach (var stmt in importedProgram.Statements) - { - if (stmt is SessionDeclNode session) - { - if (!_sessions.ContainsKey(session.Name)) - { - _sessions[session.Name] = session; - } - else - { - ErrorReporter.ReportWarning($"Session '{session.Name}' from '{mindLink.FileName}' conflicts with existing definition", 0, 0, "TYPE014"); - } - } - } - - // Übernehme Tranceifies - foreach (var stmt in importedProgram.Statements) - { - if (stmt is TranceifyDeclNode trance) - { - if (!_tranceifies.ContainsKey(trance.Name)) - { - _tranceifies[trance.Name] = trance; - } - else - { - ErrorReporter.ReportWarning($"Tranceify '{trance.Name}' from '{mindLink.FileName}' conflicts with existing definition", 0, 0, "TYPE015"); - } - } - } - - // Übernehme Funktionen - foreach (var stmt in importedProgram.Statements) - { - if (stmt is FunctionDeclNode func) - { - if (_globals.Resolve(func.Name) == null) - { - _globals.Define(new Symbol(func.Name, func.ReturnType ?? "unknown")); - } - else - { - ErrorReporter.ReportWarning($"Function '{func.Name}' from '{mindLink.FileName}' conflicts with existing definition", 0, 0, "TYPE016"); - } - } - } - - // Übernehme globale Variablen - foreach (var stmt in importedProgram.Statements) - { - if (stmt is VarDeclNode varDecl) - { - if (_globals.Resolve(varDecl.Identifier) == null) - { - _globals.Define(new Symbol(varDecl.Identifier, varDecl.TypeName ?? "unknown")); - } - else - { - ErrorReporter.ReportWarning($"Variable '{varDecl.Identifier}' from '{mindLink.FileName}' conflicts with existing definition", 0, 0, "TYPE017"); - } - } - } - - _importedFiles.Add(mindLink.FileName); - } - catch (Exception ex) - { - ErrorReporter.Report($"Failed to import '{mindLink.FileName}': {ex.Message}", 0, 0, "TYPE018"); - } - } - - private void CheckSharedTranceVarDeclaration(SharedTranceVarDeclNode shared) - { - var sharedType = InferExpressionType(shared.Initializer); - if (shared.TypeName != null && sharedType != null && shared.TypeName != sharedType && !IsTypeCompatible(shared.TypeName, sharedType)) - { - ErrorReporter.Report($"Type mismatch: sharedTrance variable '{shared.Identifier}' declared as '{shared.TypeName}' but initializer is '{sharedType}'", 0, 0, "TYPE020"); - } - if (!_globals.Define(new Symbol(shared.Identifier, shared.TypeName ?? sharedType))) - { - ErrorReporter.Report($"sharedTrance variable '{shared.Identifier}' already defined", 0, 0, "TYPE021"); - } - } - - private void CheckLabelDeclaration(LabelNode label) - { - if (_labelsInScope.Contains(label.Name)) - { - ErrorReporter.Report($"Label '{label.Name}' already defined in scope", 0, 0, "TYPE022"); - } - _labelsInScope.Add(label.Name); - } - - private void CheckSinkToStatement(SinkToNode sinkTo) - { - if (!_labelsInScope.Contains(sinkTo.LabelName)) - { - ErrorReporter.Report($"sinkTo label '{sinkTo.LabelName}' not found in scope", 0, 0, "TYPE030"); - } - } - - private void CheckEntranceBlock(EntranceBlockNode entrance) - { - foreach (var s in entrance.Statements) - CheckStatement(s); - } - - private void CheckAssertStatement(AssertStatementNode assertStmt) - { - var conditionType = InferExpressionType(assertStmt.Condition); - if (conditionType != "boolean") - { - ErrorReporter.Report($"Assert condition must be boolean, got '{conditionType}'", 0, 0, "TYPE031"); - } - } - - private void CheckSessionMember(SessionMemberNode member) - { - // Prüfe die eigentliche Deklaration - CheckStatement(member.Declaration); - } - - private void CheckExpression(IExpression? expr) - { - if (expr == null) return; - switch (expr) - { - case LiteralExpressionNode lit: - CheckLiteralExpression(lit); - break; - case BinaryExpressionNode bin: - CheckBinaryExpression(bin); - break; - case UnaryExpressionNode unary: - CheckUnaryExpression(unary); - break; - case ParenthesizedExpressionNode paren: - CheckExpression(paren.Expression); - break; - case AssignmentExpressionNode assign: - CheckAssignmentExpression(assign); - break; - case CallExpressionNode call: - CheckCallExpression(call); - break; - case IdentifierExpressionNode id: - CheckIdentifierExpression(id); - break; - case ArrayAccessExpressionNode arrayAccess: - CheckArrayAccessExpression(arrayAccess); - break; - case ArrayLiteralExpressionNode arrayLit: - CheckArrayLiteralExpression(arrayLit); - break; - case FieldAccessExpressionNode fieldAccess: - CheckFieldAccessExpression(fieldAccess); - break; - case RecordLiteralExpressionNode recordLit: - CheckRecordLiteralExpression(recordLit); - break; - case SessionInstantiationNode sessionInst: - CheckSessionInstantiation(sessionInst); - break; - case MethodCallExpressionNode methodCall: - CheckMethodCallExpression(methodCall); - break; - default: - ErrorReporter.ReportWarning($"Unsupported expression type: {expr.GetType().Name}", 0, 0, "TYPE999"); - break; - } - } - - private void CheckLiteralExpression(LiteralExpressionNode lit) - { - switch (lit.LiteralType) - { - case "number": - if (!double.TryParse(lit.Value, out _)) - { - ErrorReporter.Report($"Invalid numeric literal: {lit.Value}", 0, 0, "TYPE032"); - } - break; - case "string": - // String-Literale sind immer gültig - break; - case "boolean": - if (lit.Value != "true" && lit.Value != "false") - { - ErrorReporter.Report($"Invalid boolean literal: {lit.Value}", 0, 0, "TYPE033"); - } - break; - default: - ErrorReporter.Report($"Unknown literal type: {lit.LiteralType}", 0, 0, "TYPE034"); - break; - } - } - - private void CheckBinaryExpression(BinaryExpressionNode bin) - { - CheckExpression(bin.Left); - CheckExpression(bin.Right); - - var leftType = InferExpressionType(bin.Left); - var rightType = InferExpressionType(bin.Right); - - // Prüfe Operator-Kompatibilität - if (!IsOperatorCompatible(bin.Operator, leftType, rightType)) - { - ErrorReporter.Report($"Operator '{bin.Operator}' not compatible with types '{leftType}' and '{rightType}'", 0, 0, "TYPE035"); - } - } - - private void CheckUnaryExpression(UnaryExpressionNode unary) - { - CheckExpression(unary.Operand); - - var operandType = InferExpressionType(unary.Operand); - if (!IsUnaryOperatorCompatible(unary.Operator, operandType)) - { - ErrorReporter.Report($"Unary operator '{unary.Operator}' not compatible with type '{operandType}'", 0, 0, "TYPE036"); - } - } - - private void CheckAssignmentExpression(AssignmentExpressionNode assign) - { - CheckExpression(assign.Value); - - // Prüfe ob Variable existiert - var symbol = _globals.Resolve(assign.Identifier); - if (symbol == null) - { - ErrorReporter.Report($"Cannot assign to undefined variable '{assign.Identifier}'", 0, 0, "TYPE037"); - return; - } - - var valueType = InferExpressionType(assign.Value); - var symbolTypeName = symbol.Type?.ToString() ?? symbol.TypeName; - - if (symbolTypeName != null && valueType != null && symbolTypeName != valueType && !IsTypeCompatible(symbolTypeName, valueType)) - { - ErrorReporter.Report($"Cannot assign value of type '{valueType}' to variable '{assign.Identifier}' of type '{symbolTypeName}'", 0, 0, "TYPE038"); - } - } - - private void CheckCallExpression(CallExpressionNode call) - { - CheckExpression(call.Callee); - - foreach (var arg in call.Arguments) - { - CheckExpression(arg); - } - - // Prüfe Builtin-Funktionen - if (call.Callee is IdentifierExpressionNode id) - { - var returnType = InferBuiltinReturnType(id.Name); - if (returnType == null) - { - ErrorReporter.ReportWarning($"Unknown function '{id.Name}'", 0, 0, "TYPE039"); - } - } - } - - private void CheckIdentifierExpression(IdentifierExpressionNode id) - { - var symbol = _globals.Resolve(id.Name); - if (symbol == null) - { - ErrorReporter.Report($"Undefined variable '{id.Name}'", 0, 0, "TYPE040"); - } - } - - private void CheckArrayAccessExpression(ArrayAccessExpressionNode arrayAccess) - { - CheckExpression(arrayAccess.Array); - CheckExpression(arrayAccess.Index); - - var arrayType = InferExpressionType(arrayAccess.Array); - var indexType = InferExpressionType(arrayAccess.Index); - - if (arrayType != "array") - { - ErrorReporter.Report($"Cannot access index on non-array type '{arrayType}'", 0, 0, "TYPE041"); - } - - if (indexType != "number" && indexType != "int") - { - ErrorReporter.Report($"Array index must be number, got '{indexType}'", 0, 0, "TYPE042"); - } - } - - private void CheckArrayLiteralExpression(ArrayLiteralExpressionNode arrayLit) - { - foreach (var element in arrayLit.Elements) - { - CheckExpression(element); - } - } - - private void CheckFieldAccessExpression(FieldAccessExpressionNode fieldAccess) - { - CheckExpression(fieldAccess.Target); - - var targetType = InferExpressionType(fieldAccess.Target); - if (targetType != "record" && targetType != "session") - { - ErrorReporter.Report($"Cannot access field on non-record/session type '{targetType}'", 0, 0, "TYPE043"); - } - } - - private void CheckRecordLiteralExpression(RecordLiteralExpressionNode recordLit) - { - foreach (var field in recordLit.Fields) - { - CheckExpression(field.Value); - } - } - - private void CheckSessionInstantiation(SessionInstantiationNode sessionInst) - { - if (!_sessions.ContainsKey(sessionInst.SessionName)) - { - ErrorReporter.Report($"Undefined session '{sessionInst.SessionName}'", 0, 0, "TYPE044"); - } - } - - private void CheckMethodCallExpression(MethodCallExpressionNode methodCall) - { - CheckExpression(methodCall.Target); - - foreach (var arg in methodCall.Arguments) - { - CheckExpression(arg); - } - } - - // Hilfsmethoden für Typprüfung - private bool IsValidType(string? type) - { - if (string.IsNullOrEmpty(type)) return true; // null bedeutet "infer" - - return type switch - { - "string" => true, - "number" => true, - "int" => true, - "boolean" => true, - "array" => true, - "record" => true, - "session" => true, - "tranceify" => true, - "unknown" => true, - _ => false - }; - } - - private bool IsTypeCompatible(string targetType, string sourceType) - { - if (targetType == sourceType) return true; - - // Numerische Kompatibilität - if ((targetType == "number" && sourceType == "int") || - (targetType == "int" && sourceType == "number")) - { - return true; - } - - // Array-Kompatibilität - if (targetType == "array" && sourceType == "array") - { - return true; - } - - return false; - } - - private bool IsOperatorCompatible(string op, string? leftType, string? rightType) - { - return op switch - { - "+" => IsNumericOrString(leftType) && IsNumericOrString(rightType), - "-" => IsNumeric(leftType) && IsNumeric(rightType), - "*" => IsNumeric(leftType) && IsNumeric(rightType), - "/" => IsNumeric(leftType) && IsNumeric(rightType), - "==" => true, // Alle Typen können verglichen werden - "!=" => true, - ">" => IsNumeric(leftType) && IsNumeric(rightType), - "<" => IsNumeric(leftType) && IsNumeric(rightType), - ">=" => IsNumeric(leftType) && IsNumeric(rightType), - "<=" => IsNumeric(leftType) && IsNumeric(rightType), - "&&" => leftType == "boolean" && rightType == "boolean", - "||" => leftType == "boolean" && rightType == "boolean", - _ => false - }; - } - - private bool IsUnaryOperatorCompatible(string op, string? operandType) - { - return op switch - { - "-" => IsNumeric(operandType), - "!" => operandType == "boolean", - _ => false - }; - } - - private bool IsNumeric(string? type) - { - return type == "number" || type == "int"; - } - - private bool IsNumericOrString(string? type) - { - return IsNumeric(type) || type == "string"; - } - - // Einfache Typinferenz für Literale, Record-Literale, Identifier - private string? InferExpressionType(IExpression? expr) - { - if (expr == null) return null; - switch (expr) - { - case LiteralExpressionNode lit: - return lit.LiteralType; - case BinaryExpressionNode bin: - var leftType = InferExpressionType(bin.Left); - var rightType = InferExpressionType(bin.Right); - var binType = InferBinaryType(bin.Operator, leftType, rightType); - if (binType == "unknown") - ErrorReporter.Report($"Type of binary expression could not be inferred (unknown type)", 0, 0, "TYPE900"); - return binType; - case UnaryExpressionNode unary: - var operandType = InferExpressionType(unary.Operand); - var unaryType = InferUnaryType(unary.Operator, operandType); - if (unaryType == "unknown") - ErrorReporter.Report($"Type of unary expression could not be inferred (unknown type)", 0, 0, "TYPE901"); - return unaryType; - case ParenthesizedExpressionNode paren: - return InferExpressionType(paren.Expression); - case AssignmentExpressionNode assign: - return InferExpressionType(assign.Value); - case IdentifierExpressionNode id: - var sym = _globals.Resolve(id.Name); - if (sym?.TypeName == "unknown") - ErrorReporter.Report($"Type of variable '{id.Name}' is unknown", 0, 0, "TYPE902"); - return sym?.TypeName; - case CallExpressionNode call: - var callType = InferCallType(call); - if (callType == "unknown") - ErrorReporter.Report($"Type of function call could not be inferred (unknown type)", 0, 0, "TYPE903"); - return callType; - case ArrayLiteralExpressionNode arrayLit: - return "array"; - case ArrayAccessExpressionNode arrayAccess: - var arrType = InferArrayAccessType(arrayAccess); - if (arrType == "unknown") - ErrorReporter.Report($"Type of array access could not be inferred (unknown type)", 0, 0, "TYPE904"); - return arrType; - case FieldAccessExpressionNode fieldAccess: - var fieldType = InferFieldAccessType(fieldAccess); - if (fieldType == "unknown") - ErrorReporter.Report($"Type of field access could not be inferred (unknown type)", 0, 0, "TYPE905"); - return fieldType; - default: - ErrorReporter.Report($"Type could not be inferred (unknown type)", 0, 0, "TYPE999"); - return "unknown"; - } - } - - private string? InferBinaryType(string op, string? leftType, string? rightType) - { - // Erweiterte Typinferenz für binäre Operatoren - switch (op) - { - case "+": - if (leftType == "string" || rightType == "string") return "string"; - if (leftType == "number" && rightType == "number") return "number"; - return "unknown"; - case "-": - case "*": - case "/": - case "%": - if (leftType == "number" && rightType == "number") return "number"; - return "unknown"; - case "==": - case "!=": - case "youAreFeelingVerySleepy": - case "notSoDeep": - return "boolean"; - case ">": - case "<": - case ">=": - case "<=": - case "lookAtTheWatch": - case "fallUnderMySpell": - case "deeplyGreater": - case "deeplyLess": - if (leftType == "number" && rightType == "number") return "boolean"; - return "unknown"; - case "&&": - case "||": - if (leftType == "boolean" && rightType == "boolean") return "boolean"; - return "unknown"; - default: - return "unknown"; - } - } - - private string? InferUnaryType(string op, string? operandType) - { - switch (op) - { - case "!": - if (operandType == "boolean") return "boolean"; - return "unknown"; - case "+": - case "-": - if (operandType == "number") return "number"; - return "unknown"; - default: - return "unknown"; - } - } - - private string? InferCallType(CallExpressionNode call) - { - // Builtin-Funktionen Typinferenz - if (call.Callee is IdentifierExpressionNode id) - { - return InferBuiltinReturnType(id.Name); - } - return "unknown"; - } - - private string? InferBuiltinReturnType(string functionName) - { - // Umfassende Builtin-Funktionen Typinferenz - switch (functionName) - { - // Mathematische Funktionen - case "Abs": - case "Sin": - case "Cos": - case "Tan": - case "Sqrt": - case "Pow": - case "Floor": - case "Ceiling": - case "Round": - case "Log": - case "Log10": - case "Exp": - case "Max": - case "Min": - case "Random": - case "Factorial": - case "GCD": - case "LCM": - case "DegreesToRadians": - case "RadiansToDegrees": - case "Asin": - case "Acos": - case "Atan": - case "Atan2": - return "number"; - - // String-Funktionen - case "Length": - case "IndexOf": - case "LastIndexOf": - case "CountOccurrences": - return "number"; - case "Substring": - case "ToUpper": - case "ToLower": - case "Trim": - case "TrimStart": - case "TrimEnd": - case "Replace": - case "PadLeft": - case "PadRight": - case "Reverse": - case "Capitalize": - case "TitleCase": - case "RemoveWhitespace": - case "ToString": - case "Base64Encode": - case "Base64Decode": - case "HashMD5": - case "HashSHA256": - case "FormatDateTime": - case "GetCurrentDate": - case "GetCurrentTimeString": - case "GetCurrentDateTime": - case "GetCurrentDirectory": - case "GetMachineName": - case "GetUserName": - case "GetOSVersion": - case "GetFileExtension": - case "GetFileName": - case "GetDirectoryName": - case "ToJson": - return "string"; - - // Boolean-Funktionen - case "Contains": - case "StartsWith": - case "EndsWith": - case "ArrayContains": - case "FileExists": - case "DirectoryExists": - case "IsLeapYear": - case "ToBoolean": - return "boolean"; - - // Array-Funktionen - case "ArrayLength": - return "number"; - case "ArrayGet": - case "ArraySlice": - case "ArrayConcat": - case "ArrayReverse": - case "ArraySort": - case "ArrayUnique": - case "ArrayFilter": - case "Split": - return "array"; - - // Konvertierungsfunktionen - case "ToInt": - return "number"; - case "ToDouble": - return "number"; - case "ToChar": - return "string"; - - // Void-Funktionen (kein Rückgabewert) - case "Observe": - case "Drift": - case "DeepTrance": - case "HypnoticCountdown": - case "TranceInduction": - case "HypnoticVisualization": - case "ProgressiveRelaxation": - case "HypnoticSuggestion": - case "TranceDeepening": - case "HypnoticBreathing": - case "HypnoticAnchoring": - case "HypnoticRegression": - case "HypnoticFutureProgression": - case "WriteFile": - case "AppendFile": - case "WriteLines": - case "CreateDirectory": - case "ClearScreen": - case "Beep": - case "Exit": - case "DebugPrint": - case "DebugPrintType": - case "DebugPrintMemory": - case "DebugPrintStackTrace": - case "DebugPrintEnvironment": - case "PlaySound": - case "Vibrate": - return "void"; - - // Zeit-Funktionen - case "GetCurrentTime": - case "GetDayOfWeek": - case "GetDayOfYear": - case "GetDaysInMonth": - case "GetFileSize": - case "GetProcessorCount": - case "GetWorkingSet": - return "number"; - - default: - return "unknown"; - } - } - - private string? InferArrayAccessType(ArrayAccessExpressionNode arrayAccess) - { - var arrayType = InferExpressionType(arrayAccess.Array); - if (arrayType == "array") - { - // Für Arrays geben wir "unknown" zurück, da wir den Elementtyp nicht kennen - return "unknown"; - } - return "unknown"; - } - - private string? InferFieldAccessType(FieldAccessExpressionNode fieldAccess) - { - var objectType = InferExpressionType(fieldAccess.Target); - - // Session-Member-Zugriff - if (!string.IsNullOrEmpty(objectType) && _sessions.ContainsKey(objectType)) - { - var session = _sessions[objectType]; - foreach (var member in session.Members) - { - if (member.Declaration is VarDeclNode varDecl && varDecl.Identifier == fieldAccess.FieldName) - { - return varDecl.TypeName; - } - } - } - - // Tranceify-Member-Zugriff - if (!string.IsNullOrEmpty(objectType) && _tranceifies.ContainsKey(objectType)) - { - var tranceify = _tranceifies[objectType]; - foreach (var member in tranceify.Members) - { - if (member is VarDeclNode varDecl && varDecl.Identifier == fieldAccess.FieldName) - { - return varDecl.TypeName; - } - } - } - - return "unknown"; - } - - // Erweiterte Validierung für Session-Definitionen - private void ValidateSession(SessionDeclNode session) - { - var sessionSymbols = new Dictionary(); - - foreach (var member in session.Members) - { - if (member.Declaration is VarDeclNode varDecl) - { - if (sessionSymbols.ContainsKey(varDecl.Identifier)) - { - ErrorReporter.Report($"Duplicate member '{varDecl.Identifier}' in session '{session.Name}'", 0, 0, "TYPE040"); - } - else - { - sessionSymbols[varDecl.Identifier] = varDecl.TypeName ?? "unknown"; - } - } - else if (member.Declaration is FunctionDeclNode funcDecl) - { - if (sessionSymbols.ContainsKey(funcDecl.Name)) - { - ErrorReporter.Report($"Duplicate method '{funcDecl.Name}' in session '{session.Name}'", 0, 0, "TYPE041"); - } - else - { - sessionSymbols[funcDecl.Name] = funcDecl.ReturnType ?? "void"; - } - } - } - } - - // Erweiterte Validierung für Tranceify-Definitionen - private void ValidateTranceify(TranceifyDeclNode tranceify) - { - var fieldNames = new HashSet(); - - foreach (var member in tranceify.Members) - { - if (member is VarDeclNode varDecl) - { - if (fieldNames.Contains(varDecl.Identifier)) - { - ErrorReporter.Report($"Duplicate field '{varDecl.Identifier}' in tranceify '{tranceify.Name}'", 0, 0, "TYPE050"); - } - else - { - fieldNames.Add(varDecl.Identifier); - } - } - } - } - - private string? GetCachedType(string key) - { - return _typeCache.TryGetValue(key, out var type) ? type : null; - } - - private void CacheType(string key, string? type) - { - if (_typeCache.Count > 1000) // Cache-Größe begrenzen - { - _typeCache.Clear(); - } - _typeCache[key] = type; - } - } -} diff --git a/HypnoScript.Compiler/CodeGen/ILCodeGenerator.cs b/HypnoScript.Compiler/CodeGen/ILCodeGenerator.cs deleted file mode 100644 index 0f70f55..0000000 --- a/HypnoScript.Compiler/CodeGen/ILCodeGenerator.cs +++ /dev/null @@ -1,530 +0,0 @@ -using System.Reflection; -using System.Reflection.Emit; -using HypnoScript.LexerParser.AST; -using HypnoScript.Runtime; - -namespace HypnoScript.Compiler.CodeGen -{ - public class ILCodeGenerator - { - public required ILGenerator _il; - private readonly Dictionary _locals = new(); - private readonly Stack<(Label start, Label end)> _loopContext = new(); - - public Action Generate(ProgramNode program) - { - var method = new DynamicMethod("HypnoMain", typeof(void), Type.EmptyTypes); - _il = method.GetILGenerator(); - - foreach (var stmt in program.Statements) - { - EmitStatement(stmt); - } - - _il.Emit(OpCodes.Ret); - - var action = (Action)method.CreateDelegate(typeof(Action)); - return action; - } - - private void EmitStatement(IStatement stmt) - { - switch (stmt) - { - case VarDeclNode varDecl: - EmitVarDecl(varDecl); - break; - case ObserveStatementNode obs: - EmitExpression(obs.Expression); - // Call HypnoBuiltins.Observe for enterprise-grade logging/output handling - var observeMethod = typeof(HypnoBuiltins).GetMethod(nameof(HypnoBuiltins.Observe)) ?? throw new InvalidOperationException("Method HypnoBuiltins.Observe not found."); - _il.Emit(OpCodes.Call, observeMethod); - break; - case DriftStatementNode drift: - EmitExpression(drift.Milliseconds); - // Call HypnoBuiltins.Drift - var driftMethod = typeof(HypnoBuiltins).GetMethod(nameof(HypnoBuiltins.Drift)) ?? throw new InvalidOperationException("Method HypnoBuiltins.Drift not found."); - _il.Emit(OpCodes.Call, driftMethod); - break; - case ExpressionStatementNode exprStmt: - EmitExpression(exprStmt.Expression); - // Pop the result since we don't need it - _il.Emit(OpCodes.Pop); - break; - case IfStatementNode ifStmt: - EmitIfStatement(ifStmt); - break; - case WhileStatementNode whileStmt: - EmitWhileStatement(whileStmt); - break; - case LoopStatementNode loopStmt: - EmitLoopStatement(loopStmt); - break; - case SnapStatementNode: - // Break - jump to end of current loop - if (_loopContext.Count > 0) - { - var (_, endLabel) = _loopContext.Peek(); - _il.Emit(OpCodes.Br, endLabel); - } - else - { - throw new InvalidOperationException("Break statement outside of loop context"); - } - break; - case SinkStatementNode: - // Continue - jump to start of current loop - if (_loopContext.Count > 0) - { - var (startLabel, _) = _loopContext.Peek(); - _il.Emit(OpCodes.Br, startLabel); - } - else - { - throw new InvalidOperationException("Continue statement outside of loop context"); - } - break; - case BlockStatementNode block: - // Process each statement in the block - foreach (var s in block.Statements) - { - EmitStatement(s); - } - break; - case FunctionDeclNode funcDecl: - EmitFunction(funcDecl); - break; - case SessionDeclNode sessionDecl: - EmitSessionDeclaration(sessionDecl); - break; - case TranceifyDeclNode tranceifyDecl: - EmitTranceifyDeclaration(tranceifyDecl); - break; - case ReturnStatementNode returnStmt: - if (returnStmt.Expression != null) - { - EmitExpression(returnStmt.Expression); - } - _il.Emit(OpCodes.Ret); - break; - case EntranceBlockNode entrance: - foreach (var s in entrance.Statements) - { - EmitStatement(s); - } - break; - default: - // Centralized error handling for unsupported statement types - throw new NotSupportedException($"Unsupported statement type: {stmt.GetType().Name}"); - } - } - - // Runtime-level extension: handling If statements - private void EmitIfStatement(IfStatementNode ifStmt) - { - // Evaluate the condition - EmitExpression(ifStmt.Condition); - // Unbox to boolean for condition evaluation; assuming a helper exists - _il.Emit(OpCodes.Call, typeof(ILCodeGenerator).GetMethod(nameof(UnboxToBool), BindingFlags.Static | BindingFlags.NonPublic)!); - - // Emit branch instructions with labels for true and end segments - Label elseLabel = _il.DefineLabel(); - Label endLabel = _il.DefineLabel(); - - _il.Emit(OpCodes.Brfalse, elseLabel); - // Handle then branch - foreach (var stmt in ifStmt.ThenBranch) - { - EmitStatement(stmt); - } - _il.Emit(OpCodes.Br, endLabel); - - // Else branch, if provided - _il.MarkLabel(elseLabel); - if (ifStmt.ElseBranch != null) - { - foreach (var stmt in ifStmt.ElseBranch) - { - EmitStatement(stmt); - } - } - _il.MarkLabel(endLabel); - } - - // Runtime-level extension: handling While loops - private void EmitWhileStatement(WhileStatementNode whileStmt) - { - Label loopStart = _il.DefineLabel(); - Label loopEnd = _il.DefineLabel(); - - // Push loop context for break/continue support - _loopContext.Push((loopStart, loopEnd)); - - _il.MarkLabel(loopStart); - EmitExpression(whileStmt.Condition); - _il.Emit(OpCodes.Call, typeof(ILCodeGenerator).GetMethod(nameof(UnboxToBool), BindingFlags.Static | BindingFlags.NonPublic)!); - _il.Emit(OpCodes.Brfalse, loopEnd); - - foreach (var stmt in whileStmt.Body) - { - EmitStatement(stmt); - } - _il.Emit(OpCodes.Br, loopStart); - _il.MarkLabel(loopEnd); - - // Pop loop context - _loopContext.Pop(); - } - - // Helper method to unbox an object to a boolean value - private static bool UnboxToBool(object obj) - { - if (obj is bool b) - { - return b; - } - // Fallback: attempt to convert common types if necessary - if (obj is int i) - { - return i != 0; - } - return false; - } - - private void EmitVarDecl(VarDeclNode decl) - { - // Deklariere Local - var local = _il.DeclareLocal(typeof(object)); - _locals[decl.Identifier] = local; - - if (decl.FromExternal) - { - // Konsoleingabe - _il.Emit(OpCodes.Ldstr, $"Input for {decl.Identifier}: "); - _il.Emit(OpCodes.Call, typeof(Console).GetMethod("Write", new[] { typeof(string) })!); - _il.Emit(OpCodes.Call, typeof(Console).GetMethod(nameof(Console.ReadLine), Type.EmptyTypes)!); - } - else if (decl.Initializer != null) - { - EmitExpression(decl.Initializer); - } - else - { - // null - _il.Emit(OpCodes.Ldnull); - } - - _il.Emit(OpCodes.Stloc, local); - } - - private void EmitExpression(IExpression expr) - { - switch (expr) - { - case LiteralExpressionNode lit: - EmitLiteral(lit); - break; - case IdentifierExpressionNode id: - if (_locals.TryGetValue(id.Name, out var local)) - { - _il.Emit(OpCodes.Ldloc, local); - } - else - { - // fallback: push null - _il.Emit(OpCodes.Ldnull); - } - break; - case BinaryExpressionNode bin: - EmitBinary(bin); - break; - case UnaryExpressionNode unary: - EmitUnary(unary); - break; - case ParenthesizedExpressionNode paren: - EmitExpression(paren.Expression); - break; - case AssignmentExpressionNode assign: - EmitAssignment(assign); - break; - case CallExpressionNode call: - EmitCall(call); - break; - case MethodCallExpressionNode methodCall: - EmitMethodCall(methodCall); - break; - case SessionInstantiationNode sessionInst: - EmitSessionInstantiation(sessionInst); - break; - case FieldAccessExpressionNode fieldAccess: - EmitFieldAccess(fieldAccess); - break; - case RecordLiteralExpressionNode recordLit: - EmitRecordLiteral(recordLit); - break; - case ArrayAccessExpressionNode arrayAccess: - EmitArrayAccess(arrayAccess); - break; - case ArrayLiteralExpressionNode arrayLit: - EmitArrayLiteral(arrayLit); - break; - } - } - - private void EmitLiteral(LiteralExpressionNode lit) - { - // Alles als object -> Boxen - if (lit.LiteralType == "number") - { - if (lit.Value.Contains(".")) - { - if (double.TryParse(lit.Value, out double d)) - { - _il.Emit(OpCodes.Ldc_R8, d); - _il.Emit(OpCodes.Box, typeof(double)); - } - } - else - { - if (int.TryParse(lit.Value, out int i)) - { - _il.Emit(OpCodes.Ldc_I4, i); - _il.Emit(OpCodes.Box, typeof(int)); - } - } - } - else if (lit.LiteralType == "boolean") - { - bool b = (lit.Value == "true"); - _il.Emit(b ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0); - _il.Emit(OpCodes.Box, typeof(bool)); - } - else - { - // string - _il.Emit(OpCodes.Ldstr, lit.Value); - } - } - - private void EmitBinary(BinaryExpressionNode bin) - { - EmitExpression(bin.Left); - EmitExpression(bin.Right); - - // wir haben 2 x object auf dem Stack -> wir konvertieren (double) für +, -, etc - switch (bin.Operator) - { - case "+": - case "-": - case "*": - case "/": - // Unbox als double -> Rechenoperation -> Box - _il.Emit(OpCodes.Call, typeof(ILCodeGenerator).GetMethod(nameof(UnboxToDouble), BindingFlags.Static | BindingFlags.NonPublic)!); - _il.Emit(OpCodes.Call, typeof(ILCodeGenerator).GetMethod(nameof(UnboxToDouble), BindingFlags.Static | BindingFlags.NonPublic)!); - - switch (bin.Operator) - { - case "+": _il.Emit(OpCodes.Add); break; - case "-": _il.Emit(OpCodes.Sub); break; - case "*": _il.Emit(OpCodes.Mul); break; - case "/": _il.Emit(OpCodes.Div); break; - } - - _il.Emit(OpCodes.Box, typeof(double)); - break; - - case "==": - // call Equals - _il.Emit(OpCodes.Call, typeof(object).GetMethod(nameof(object.Equals), new[] { typeof(object), typeof(object) })!); - break; - } - } - - private void EmitUnary(UnaryExpressionNode unary) - { - // Implement unary expression emission logic - } - - private void EmitAssignment(AssignmentExpressionNode assign) - { - // Implement assignment expression emission logic - } - - private void EmitCall(CallExpressionNode call) - { - if (call.Callee is IdentifierExpressionNode id) - { - switch (id.Name) - { - case "drift": - // drift(x) - if (call.Arguments.Count != 1) - throw new Exception("drift benötigt genau 1 Argument"); - - EmitExpression(call.Arguments[0]); - // -> Unbox to int - _il.Emit(OpCodes.Call, typeof(ILCodeGenerator).GetMethod(nameof(UnboxToInt), BindingFlags.Static | BindingFlags.NonPublic)!); - - // Call HypnoBuiltins.Drift(int) - _il.Emit(OpCodes.Call, typeof(HypnoBuiltins).GetMethod(nameof(HypnoBuiltins.Drift))!); - break; - - default: - // Runtime-Level: Dynamische Funktionsaufrufe unterstützen - // Suche nach einer statischen Methode in HypnoBuiltins mit dem Namen der Funktion - var candidates = typeof(HypnoBuiltins).GetMethods() - .Where(m => m.Name == id.Name && m.IsStatic) - .ToList(); - - if (!candidates.Any()) - throw new NotSupportedException($"Unbekannte Funktion: {id.Name}"); - - // Wähle die Methode, die zur Anzahl der Parameter passt - var targetMethod = candidates.FirstOrDefault(m => m.GetParameters().Length == call.Arguments.Count) ?? throw new Exception($"Funktion {id.Name} mit {call.Arguments.Count} Argument(en) wurde nicht gefunden."); - - // Argumente evaluieren und auf den erwarteten Typ casten, falls nötig - var parameters = targetMethod.GetParameters(); - for (int i = 0; i < call.Arguments.Count; i++) - { - EmitExpression(call.Arguments[i]); - - // Runtime-Level: Falls der Parameter nicht vom Typ object ist, erfolgt eine Unboxing-Konvertierung - if (parameters[i].ParameterType != typeof(object)) - { - var paramType = parameters[i].ParameterType; - // Es erfolgt hier eine einfache Fallunterscheidung für int und double - if (paramType == typeof(int)) - { - _il.Emit(OpCodes.Call, typeof(ILCodeGenerator).GetMethod(nameof(UnboxToInt), BindingFlags.Static | BindingFlags.NonPublic)!); - } - else if (paramType == typeof(double)) - { - _il.Emit(OpCodes.Call, typeof(ILCodeGenerator).GetMethod(nameof(UnboxToDouble), BindingFlags.Static | BindingFlags.NonPublic)!); - } - // Weitere Typkonvertierungen können hier hinzugefügt werden - } - } - - _il.Emit(OpCodes.Call, targetMethod); - break; - } - } - else - { - throw new NotSupportedException("Nur Funktionsaufrufe über Bezeichner werden unterstützt."); - } - } - - private static double UnboxToDouble(object obj) - { - if (obj is int i) return i; - if (obj is double d) return d; - return 0.0; - } - - private static int UnboxToInt(object obj) - { - if (obj is int i) return i; - if (obj is double d) return (int)d; - return 0; - } - - private void EmitFunction(FunctionDeclNode funcDecl) - { - // Erweiterung: Dynamische Methoden für Funktionen erstellen - // Parameter-Handling und Lokale Variablen initialisieren - // ...implementierung... - } - - // Runtime-level extension: handling Loop statements - private void EmitLoopStatement(LoopStatementNode loopStmt) - { - Label loopStart = _il.DefineLabel(); - Label loopEnd = _il.DefineLabel(); - - // Push loop context for break/continue support - _loopContext.Push((loopStart, loopEnd)); - - // Emit initializer - if (loopStmt.Initializer != null) - { - EmitStatement(loopStmt.Initializer); - } - - _il.MarkLabel(loopStart); - - // Emit condition - EmitExpression(loopStmt.Condition); - _il.Emit(OpCodes.Call, typeof(ILCodeGenerator).GetMethod(nameof(UnboxToBool), BindingFlags.Static | BindingFlags.NonPublic)!); - _il.Emit(OpCodes.Brfalse, loopEnd); - - // Emit body - foreach (var stmt in loopStmt.Body) - { - EmitStatement(stmt); - } - - // Emit iteration - if (loopStmt.Iteration != null) - { - EmitStatement(loopStmt.Iteration); - } - - _il.Emit(OpCodes.Br, loopStart); - _il.MarkLabel(loopEnd); - - // Pop loop context - _loopContext.Pop(); - } - - private void EmitSessionDeclaration(SessionDeclNode sessionDecl) - { - // For now, just emit the members as regular statements - // In a full implementation, this would create a class type - foreach (var member in sessionDecl.Members) - { - EmitStatement(member.Declaration); - } - } - - private void EmitTranceifyDeclaration(TranceifyDeclNode tranceifyDecl) - { - // For now, just emit the members as regular variable declarations - // In a full implementation, this would create a struct type - foreach (var member in tranceifyDecl.Members) - { - EmitStatement(member); - } - } - - private void EmitMethodCall(MethodCallExpressionNode methodCall) - { - // Implement method call emission logic - } - - private void EmitSessionInstantiation(SessionInstantiationNode sessionInst) - { - // Implement session instantiation emission logic - } - - private void EmitFieldAccess(FieldAccessExpressionNode fieldAccess) - { - // Implement field access emission logic - } - - private void EmitRecordLiteral(RecordLiteralExpressionNode recordLit) - { - // Implement record literal emission logic - } - - private void EmitArrayAccess(ArrayAccessExpressionNode arrayAccess) - { - // Implement array access emission logic - } - - private void EmitArrayLiteral(ArrayLiteralExpressionNode arrayLit) - { - // Implement array literal emission logic - } - } -} diff --git a/HypnoScript.Compiler/CodeGen/ILCodeOptimizer.cs b/HypnoScript.Compiler/CodeGen/ILCodeOptimizer.cs deleted file mode 100644 index c70916c..0000000 --- a/HypnoScript.Compiler/CodeGen/ILCodeOptimizer.cs +++ /dev/null @@ -1,76 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Reflection.Emit; - -namespace HypnoScript.Compiler.CodeGen -{ - // Runtime-Level: Definition einer einfachen Intermediate Representation (IR) für IL-Anweisungen. - public class IlInstruction - { - public OpCode Opcode { get; set; } - public object? Operand { get; set; } - - public IlInstruction(OpCode opcode, object? operand = null) - { - Opcode = opcode; - Operand = operand; - } - - public override string ToString() => Operand != null - ? $"{Opcode.Name} {Operand}" - : (Opcode.Name ?? string.Empty); - } - - public static class ILCodeOptimizer - { - // Runtime-Level: Optimiert den IL-Code, indem überflüssige Box/Unbox-Aufrufe entfernt werden. - // Diese Methode arbeitet anhand einer Liste von IlInstruction und gibt eine optimierte Liste zurück. - public static List Optimize(List instructions) - { - var optimized = new List(); - int i = 0; - while (i < instructions.Count) - { - // Prüfe auf Box/Unbox-Paare, die sich gegenseitig aufheben: - if (i < instructions.Count - 1 && - IsBoxInstruction(instructions[i]) && - IsUnboxInstruction(instructions[i + 1]) && - MatchingTypes(instructions[i], instructions[i + 1])) - { - // Diese beiden Anweisungen heben sich auf – überspringe sie - i += 2; - continue; - } - optimized.Add(instructions[i]); - i++; - } - return optimized; - } - - private static bool IsBoxInstruction(IlInstruction instr) => - instr.Opcode == OpCodes.Box; - - private static bool IsUnboxInstruction(IlInstruction instr) => - instr.Opcode == OpCodes.Unbox_Any || instr.Opcode == OpCodes.Unbox; - - // Überprüft, ob die Box/Unbox-Paare denselben Typ betreffen. - private static bool MatchingTypes(IlInstruction boxInstr, IlInstruction unboxInstr) - { - if (boxInstr.Operand is Type boxType && unboxInstr.Operand is Type unboxType) - { - return boxType == unboxType; - } - return false; - } - - // Optional: Eine Methode zur Ausgabe der IR-Instruktionen (zur Diagnose) - public static void DumpInstructions(List instructions) - { - Console.WriteLine("Optimized IL Instructions:"); - foreach (var instr in instructions) - { - Console.WriteLine(instr.ToString()); - } - } - } -} diff --git a/HypnoScript.Compiler/CodeGen/WasmCodeGenerator.cs b/HypnoScript.Compiler/CodeGen/WasmCodeGenerator.cs deleted file mode 100644 index 416ae9c..0000000 --- a/HypnoScript.Compiler/CodeGen/WasmCodeGenerator.cs +++ /dev/null @@ -1,733 +0,0 @@ -using System.Text; -using HypnoScript.LexerParser.AST; - -namespace HypnoScript.Compiler.CodeGen -{ - // WebAssembly-Codegenerator im WAT-Format - public class WasmCodeGenerator - { - private StringBuilder _wat = null!; - private int _localCounter = 0; - private int _labelCounter = 0; - private Dictionary _variableMap = new(); - private Dictionary _functionMap = new(); - private List _imports = new(); - private List _functions = new(); - - public string Generate(ProgramNode program) - { - _wat = new StringBuilder(); - _localCounter = 0; - _labelCounter = 0; - _variableMap.Clear(); - _functionMap.Clear(); - _imports.Clear(); - _functions.Clear(); - - // Standard-Imports - AddImport("env", "console_log", "(func $console_log (param i32))"); - AddImport("env", "console_log_str", "(func $console_log_str (param i32 i32))"); - AddImport("env", "drift", "(func $drift (param i32))"); - AddImport("env", "memory", "(memory (export \"memory\") 1)"); - - _wat.AppendLine("(module"); - - // Imports - foreach (var import in _imports) - { - _wat.AppendLine($" (import {import})"); - } - - // Globale Variablen für String-Speicher - _wat.AppendLine(" (global $string_offset (mut i32) (i32.const 0))"); - _wat.AppendLine(" (global $heap_offset (mut i32) (i32.const 1024))"); - - // Hilfsfunktionen - EmitHelperFunctions(); - - // Hauptfunktion - _wat.AppendLine(" (func $HypnoMain (export \"main\")"); - _wat.AppendLine(" (local $temp i32)"); - _wat.AppendLine(" (local $temp_f64 f64)"); - _wat.AppendLine(" (local $temp_str i32)"); - - // Entrance-Block zuerst ausführen - foreach (var stmt in program.Statements) - { - if (stmt is EntranceBlockNode entrance) - { - EmitStatements(entrance.Statements); - } - } - - // Dann alle anderen Statements - foreach (var stmt in program.Statements) - { - if (stmt is not EntranceBlockNode) - { - EmitStatement(stmt); - } - } - - _wat.AppendLine(" )"); - - // Weitere Funktionen - foreach (var function in _functions) - { - _wat.AppendLine(function); - } - - _wat.AppendLine(")"); - return _wat.ToString(); - } - - private void AddImport(string module, string name, string signature) - { - _imports.Add($"\"{module}\" \"{name}\" {signature}"); - } - - private void EmitHelperFunctions() - { - // String-Hilfsfunktionen - _wat.AppendLine(" ;; String-Hilfsfunktionen"); - _wat.AppendLine(" (func $store_string (param $str i32) (param $len i32) (result i32)"); - _wat.AppendLine(" (local $offset i32)"); - _wat.AppendLine(" global.get $string_offset"); - _wat.AppendLine(" local.tee $offset"); - _wat.AppendLine(" local.get $len"); - _wat.AppendLine(" i32.add"); - _wat.AppendLine(" global.set $string_offset"); - _wat.AppendLine(" local.get $offset"); - _wat.AppendLine(" )"); - - _wat.AppendLine(" (func $print_string (param $str i32) (param $len i32)"); - _wat.AppendLine(" local.get $str"); - _wat.AppendLine(" local.get $len"); - _wat.AppendLine(" call $console_log_str"); - _wat.AppendLine(" )"); - - _wat.AppendLine(" (func $print_number (param $num i32)"); - _wat.AppendLine(" local.get $num"); - _wat.AppendLine(" call $console_log"); - _wat.AppendLine(" )"); - - // Erweiterte mathematische Funktionen - _wat.AppendLine(" ;; Erweiterte mathematische Funktionen"); - _wat.AppendLine(" (func $factorial (param $n i32) (result i32)"); - _wat.AppendLine(" (local $result i32)"); - _wat.AppendLine(" i32.const 1"); - _wat.AppendLine(" local.set $result"); - _wat.AppendLine(" block"); - _wat.AppendLine(" loop"); - _wat.AppendLine(" local.get $n"); - _wat.AppendLine(" i32.const 1"); - _wat.AppendLine(" i32.le_s"); - _wat.AppendLine(" br_if 1"); - _wat.AppendLine(" local.get $result"); - _wat.AppendLine(" local.get $n"); - _wat.AppendLine(" i32.mul"); - _wat.AppendLine(" local.set $result"); - _wat.AppendLine(" local.get $n"); - _wat.AppendLine(" i32.const 1"); - _wat.AppendLine(" i32.sub"); - _wat.AppendLine(" local.set $n"); - _wat.AppendLine(" br 0"); - _wat.AppendLine(" end"); - _wat.AppendLine(" end"); - _wat.AppendLine(" local.get $result"); - _wat.AppendLine(" )"); - - // GCD-Funktion - _wat.AppendLine(" (func $gcd (param $a i32) (param $b i32) (result i32)"); - _wat.AppendLine(" (local $temp i32)"); - _wat.AppendLine(" block"); - _wat.AppendLine(" loop"); - _wat.AppendLine(" local.get $b"); - _wat.AppendLine(" i32.eqz"); - _wat.AppendLine(" br_if 1"); - _wat.AppendLine(" local.get $b"); - _wat.AppendLine(" local.set $temp"); - _wat.AppendLine(" local.get $a"); - _wat.AppendLine(" local.get $b"); - _wat.AppendLine(" i32.rem_s"); - _wat.AppendLine(" local.set $b"); - _wat.AppendLine(" local.get $temp"); - _wat.AppendLine(" local.set $a"); - _wat.AppendLine(" br 0"); - _wat.AppendLine(" end"); - _wat.AppendLine(" end"); - _wat.AppendLine(" local.get $a"); - _wat.AppendLine(" )"); - - // Array-Hilfsfunktionen - _wat.AppendLine(" ;; Array-Hilfsfunktionen"); - _wat.AppendLine(" (func $array_length (param $arr i32) (result i32)"); - _wat.AppendLine(" local.get $arr"); - _wat.AppendLine(" i32.load"); - _wat.AppendLine(" )"); - - _wat.AppendLine(" (func $array_get (param $arr i32) (param $index i32) (result i32)"); - _wat.AppendLine(" local.get $arr"); - _wat.AppendLine(" i32.const 4"); - _wat.AppendLine(" i32.add"); - _wat.AppendLine(" local.get $index"); - _wat.AppendLine(" i32.const 4"); - _wat.AppendLine(" i32.mul"); - _wat.AppendLine(" i32.add"); - _wat.AppendLine(" i32.load"); - _wat.AppendLine(" )"); - - _wat.AppendLine(" (func $array_set (param $arr i32) (param $index i32) (param $value i32)"); - _wat.AppendLine(" local.get $arr"); - _wat.AppendLine(" i32.const 4"); - _wat.AppendLine(" i32.add"); - _wat.AppendLine(" local.get $index"); - _wat.AppendLine(" i32.const 4"); - _wat.AppendLine(" i32.mul"); - _wat.AppendLine(" i32.add"); - _wat.AppendLine(" local.get $value"); - _wat.AppendLine(" i32.store"); - _wat.AppendLine(" )"); - - // String-Vergleich - _wat.AppendLine(" (func $string_equals (param $str1 i32) (param $len1 i32) (param $str2 i32) (param $len2 i32) (result i32)"); - _wat.AppendLine(" (local $i i32)"); - _wat.AppendLine(" local.get $len1"); - _wat.AppendLine(" local.get $len2"); - _wat.AppendLine(" i32.ne"); - _wat.AppendLine(" if"); - _wat.AppendLine(" i32.const 0"); - _wat.AppendLine(" return"); - _wat.AppendLine(" end"); - _wat.AppendLine(" i32.const 0"); - _wat.AppendLine(" local.set $i"); - _wat.AppendLine(" block"); - _wat.AppendLine(" loop"); - _wat.AppendLine(" local.get $i"); - _wat.AppendLine(" local.get $len1"); - _wat.AppendLine(" i32.ge_s"); - _wat.AppendLine(" br_if 1"); - _wat.AppendLine(" local.get $str1"); - _wat.AppendLine(" local.get $i"); - _wat.AppendLine(" i32.add"); - _wat.AppendLine(" i32.load8_u"); - _wat.AppendLine(" local.get $str2"); - _wat.AppendLine(" local.get $i"); - _wat.AppendLine(" i32.add"); - _wat.AppendLine(" i32.load8_u"); - _wat.AppendLine(" i32.ne"); - _wat.AppendLine(" if"); - _wat.AppendLine(" i32.const 0"); - _wat.AppendLine(" return"); - _wat.AppendLine(" end"); - _wat.AppendLine(" local.get $i"); - _wat.AppendLine(" i32.const 1"); - _wat.AppendLine(" i32.add"); - _wat.AppendLine(" local.set $i"); - _wat.AppendLine(" br 0"); - _wat.AppendLine(" end"); - _wat.AppendLine(" end"); - _wat.AppendLine(" i32.const 1"); - _wat.AppendLine(" )"); - - // Konvertierungsfunktionen - _wat.AppendLine(" ;; Konvertierungsfunktionen"); - _wat.AppendLine(" (func $int_to_string (param $num i32) (result i32)"); - _wat.AppendLine(" (local $str i32)"); - _wat.AppendLine(" (local $len i32)"); - _wat.AppendLine(" ;; Einfache Implementierung für positive Zahlen"); - _wat.AppendLine(" local.get $num"); - _wat.AppendLine(" i32.const 10"); - _wat.AppendLine(" i32.lt_s"); - _wat.AppendLine(" if"); - _wat.AppendLine(" i32.const 1"); - _wat.AppendLine(" local.set $len"); - _wat.AppendLine(" else"); - _wat.AppendLine(" i32.const 2"); - _wat.AppendLine(" local.set $len"); - _wat.AppendLine(" end"); - _wat.AppendLine(" local.get $len"); - _wat.AppendLine(" call $store_string"); - _wat.AppendLine(" local.set $str"); - _wat.AppendLine(" local.get $str"); - _wat.AppendLine(" )"); - - // Boolean-Konvertierung - _wat.AppendLine(" (func $bool_to_string (param $bool i32) (result i32)"); - _wat.AppendLine(" local.get $bool"); - _wat.AppendLine(" if"); - _wat.AppendLine(" i32.const 4 ;; \"true\""); - _wat.AppendLine(" call $store_string"); - _wat.AppendLine(" else"); - _wat.AppendLine(" i32.const 5 ;; \"false\""); - _wat.AppendLine(" call $store_string"); - _wat.AppendLine(" end"); - _wat.AppendLine(" )"); - } - - private void EmitStatements(List statements) - { - foreach (var stmt in statements) - { - EmitStatement(stmt); - } - } - - private void EmitStatement(IStatement stmt) - { - switch (stmt) - { - case VarDeclNode varDecl: - EmitVarDecl(varDecl); - break; - case ExpressionStatementNode exprStmt: - EmitExpression(exprStmt.Expression); - _wat.AppendLine(" drop ;; Verwerfe Ergebnis"); - break; - case ObserveStatementNode observe: - EmitObserve(observe); - break; - case IfStatementNode ifStmt: - EmitIf(ifStmt); - break; - case WhileStatementNode whileStmt: - EmitWhile(whileStmt); - break; - case LoopStatementNode loopStmt: - EmitLoop(loopStmt); - break; - case SnapStatementNode: - EmitSnap(); - break; - case SinkStatementNode: - EmitSink(); - break; - case FunctionDeclNode funcDecl: - EmitFunctionDeclaration(funcDecl); - break; - case SessionDeclNode sessionDecl: - EmitSessionDeclaration(sessionDecl); - break; - case TranceifyDeclNode tranceifyDecl: - EmitTranceifyDeclaration(tranceifyDecl); - break; - case DriftStatementNode drift: - EmitDrift(drift); - break; - case BlockStatementNode block: - EmitStatements(block.Statements); - break; - default: - _wat.AppendLine($" ;; Unsupported statement: {stmt.GetType().Name}"); - break; - } - } - - private void EmitVarDecl(VarDeclNode decl) - { - var varIndex = _localCounter++; - _variableMap[decl.Identifier] = varIndex; - - if (decl.Initializer != null) - { - EmitExpression(decl.Initializer); - } - else - { - _wat.AppendLine(" i32.const 0"); - } - - _wat.AppendLine($" local.set ${varIndex} ;; {decl.Identifier}"); - } - - private void EmitObserve(ObserveStatementNode observe) - { - EmitExpression(observe.Expression); - _wat.AppendLine(" call $print_number"); - } - - private void EmitIf(IfStatementNode ifStmt) - { - var elseLabel = $"else_{_labelCounter++}"; - var endLabel = $"endif_{_labelCounter++}"; - - EmitExpression(ifStmt.Condition); - _wat.AppendLine(" i32.eqz"); - _wat.AppendLine($" br_if ${elseLabel}"); - - // Then-Block - EmitStatements(ifStmt.ThenBranch); - _wat.AppendLine($" br ${endLabel}"); - - // Else-Block - if (ifStmt.ElseBranch != null) - { - _wat.AppendLine($" ${elseLabel}:"); - EmitStatements(ifStmt.ElseBranch); - } - else - { - _wat.AppendLine($" ${elseLabel}:"); - } - - _wat.AppendLine($" ${endLabel}:"); - } - - private void EmitWhile(WhileStatementNode whileStmt) - { - var loopLabel = $"while_loop_{_labelCounter++}"; - var endLabel = $"while_end_{_labelCounter++}"; - - _wat.AppendLine($" ${loopLabel}:"); - EmitExpression(whileStmt.Condition); - _wat.AppendLine(" i32.eqz"); - _wat.AppendLine($" br_if ${endLabel}"); - - EmitStatements(whileStmt.Body); - _wat.AppendLine($" br ${loopLabel}"); - - _wat.AppendLine($" ${endLabel}:"); - } - - private void EmitLoop(LoopStatementNode loopStmt) - { - var loopLabel = $"for_loop_{_labelCounter++}"; - var endLabel = $"for_end_{_labelCounter++}"; - - // Initializer - if (loopStmt.Initializer != null) - { - EmitStatement(loopStmt.Initializer); - } - - _wat.AppendLine($" ${loopLabel}:"); - EmitExpression(loopStmt.Condition); - _wat.AppendLine(" i32.eqz"); - _wat.AppendLine($" br_if ${endLabel}"); - - EmitStatements(loopStmt.Body); - - // Iteration - if (loopStmt.Iteration != null) - { - EmitStatement(loopStmt.Iteration); - } - - _wat.AppendLine($" br ${loopLabel}"); - _wat.AppendLine($" ${endLabel}:"); - } - - private void EmitSnap() - { - _wat.AppendLine(" ;; snap (break) - würde Schleife verlassen"); - } - - private void EmitSink() - { - _wat.AppendLine(" ;; sink (continue) - würde zum Schleifenanfang springen"); - } - - private void EmitDrift(DriftStatementNode drift) - { - EmitExpression(drift.Milliseconds); - _wat.AppendLine(" call $drift"); - } - - private void EmitExpression(IExpression expr) - { - switch (expr) - { - case LiteralExpressionNode lit: - EmitLiteral(lit); - break; - case BinaryExpressionNode bin: - EmitBinary(bin); - break; - case UnaryExpressionNode unary: - EmitUnary(unary); - break; - case IdentifierExpressionNode id: - EmitIdentifier(id); - break; - case CallExpressionNode call: - EmitCall(call); - break; - case AssignmentExpressionNode assign: - EmitAssignment(assign); - break; - case ArrayLiteralExpressionNode arrayLit: - EmitArrayLiteral(arrayLit); - break; - case ArrayAccessExpressionNode arrayAccess: - EmitArrayAccess(arrayAccess); - break; - case ParenthesizedExpressionNode paren: - EmitExpression(paren.Expression); - break; - default: - _wat.AppendLine($" ;; Unsupported expression: {expr.GetType().Name}"); - _wat.AppendLine(" i32.const 0"); - break; - } - } - - private void EmitLiteral(LiteralExpressionNode lit) - { - switch (lit.LiteralType) - { - case "number": - if (double.TryParse(lit.Value, out double num)) - { - if (num == (int)num) - { - _wat.AppendLine($" i32.const {(int)num}"); - } - else - { - _wat.AppendLine($" f64.const {num}"); - } - } - else - { - _wat.AppendLine(" i32.const 0"); - } - break; - case "boolean": - int boolVal = (lit.Value == "true") ? 1 : 0; - _wat.AppendLine($" i32.const {boolVal}"); - break; - case "string": - EmitStringLiteral(lit.Value); - break; - default: - _wat.AppendLine(" i32.const 0"); - break; - } - } - - private void EmitStringLiteral(string value) - { - // Vereinfachte String-Behandlung - _wat.AppendLine($" ;; String: \"{value}\""); - _wat.AppendLine(" i32.const 0 ;; Platzhalter für String-Pointer"); - } - - private void EmitBinary(BinaryExpressionNode bin) - { - EmitExpression(bin.Left); - EmitExpression(bin.Right); - - switch (bin.Operator) - { - case "+": - _wat.AppendLine(" i32.add"); - break; - case "-": - _wat.AppendLine(" i32.sub"); - break; - case "*": - _wat.AppendLine(" i32.mul"); - break; - case "/": - _wat.AppendLine(" i32.div_s"); - break; - case "%": - _wat.AppendLine(" i32.rem_s"); - break; - case "==": - case "youAreFeelingVerySleepy": - _wat.AppendLine(" i32.eq"); - break; - case "!=": - case "notSoDeep": - _wat.AppendLine(" i32.ne"); - break; - case ">": - case "lookAtTheWatch": - _wat.AppendLine(" i32.gt_s"); - break; - case "<": - case "fallUnderMySpell": - _wat.AppendLine(" i32.lt_s"); - break; - case ">=": - case "deeplyGreater": - _wat.AppendLine(" i32.ge_s"); - break; - case "<=": - case "deeplyLess": - _wat.AppendLine(" i32.le_s"); - break; - case "&&": - _wat.AppendLine(" i32.and"); - break; - case "||": - _wat.AppendLine(" i32.or"); - break; - default: - _wat.AppendLine($" ;; Unsupported operator: {bin.Operator}"); - _wat.AppendLine(" i32.const 0"); - break; - } - } - - private void EmitUnary(UnaryExpressionNode unary) - { - EmitExpression(unary.Operand); - - switch (unary.Operator) - { - case "!": - _wat.AppendLine(" i32.eqz"); - break; - case "-": - _wat.AppendLine(" i32.const 0"); - _wat.AppendLine(" i32.sub"); - break; - case "+": - // Nichts zu tun, Wert bleibt unverändert - break; - default: - _wat.AppendLine($" ;; Unsupported unary operator: {unary.Operator}"); - break; - } - } - - private void EmitIdentifier(IdentifierExpressionNode id) - { - if (_variableMap.TryGetValue(id.Name, out int varIndex)) - { - _wat.AppendLine($" local.get ${varIndex} ;; {id.Name}"); - } - else - { - _wat.AppendLine($" ;; Variable {id.Name} nicht gefunden"); - _wat.AppendLine(" i32.const 0"); - } - } - - private void EmitCall(CallExpressionNode call) - { - // Argumente auswerten - foreach (var arg in call.Arguments) - { - EmitExpression(arg); - } - - if (call.Callee is IdentifierExpressionNode funcId) - { - // Builtin-Funktionen - switch (funcId.Name) - { - case "drift": - _wat.AppendLine(" call $drift"); - break; - case "Sin": - case "Cos": - case "Tan": - case "Sqrt": - case "Pow": - case "Abs": - case "Floor": - case "Ceiling": - case "Round": - _wat.AppendLine($" ;; Mathematische Funktion: {funcId.Name}"); - _wat.AppendLine(" f64.const 0.0 ;; Platzhalter"); - break; - default: - _wat.AppendLine($" ;; Funktionsaufruf: {funcId.Name}"); - _wat.AppendLine(" i32.const 0 ;; Platzhalter"); - break; - } - } - else - { - _wat.AppendLine(" ;; Komplexer Funktionsaufruf"); - _wat.AppendLine(" i32.const 0 ;; Platzhalter"); - } - } - - private void EmitAssignment(AssignmentExpressionNode assign) - { - EmitExpression(assign.Value); - - if (_variableMap.TryGetValue(assign.Identifier, out int varIndex)) - { - _wat.AppendLine($" local.set ${varIndex} ;; {assign.Identifier}"); - } - else - { - _wat.AppendLine($" ;; Variable {assign.Identifier} nicht gefunden"); - } - } - - private void EmitArrayLiteral(ArrayLiteralExpressionNode arrayLit) - { - _wat.AppendLine(" ;; Array-Literal"); - foreach (var element in arrayLit.Elements) - { - EmitExpression(element); - } - _wat.AppendLine(" i32.const 0 ;; Platzhalter für Array"); - } - - private void EmitArrayAccess(ArrayAccessExpressionNode arrayAccess) - { - EmitExpression(arrayAccess.Array); - EmitExpression(arrayAccess.Index); - _wat.AppendLine(" ;; Array-Zugriff"); - _wat.AppendLine(" i32.const 0 ;; Platzhalter"); - } - - private void EmitFunctionDeclaration(FunctionDeclNode funcDecl) - { - _functionMap[funcDecl.Name] = _functions.Count; - - var funcCode = new StringBuilder(); - funcCode.AppendLine($" (func ${funcDecl.Name}"); - - // Parameter - for (int i = 0; i < funcDecl.Parameters.Count; i++) - { - funcCode.AppendLine($" (param ${i} i32)"); - } - - // Rückgabetyp - if (funcDecl.ReturnType != null) - { - funcCode.AppendLine($" (result i32)"); - } - - // Lokale Variablen - funcCode.AppendLine(" (local $temp i32)"); - - // Body - foreach (var stmt in funcDecl.Body) - { - // Vereinfachte Statement-Emission - funcCode.AppendLine(" ;; Statement"); - } - - funcCode.AppendLine(" )"); - _functions.Add(funcCode.ToString()); - } - - private void EmitSessionDeclaration(SessionDeclNode sessionDecl) - { - _wat.AppendLine($" ;; Session-Deklaration: {sessionDecl.Name}"); - foreach (var member in sessionDecl.Members) - { - _wat.AppendLine(" ;; Session-Member"); - } - } - - private void EmitTranceifyDeclaration(TranceifyDeclNode tranceifyDecl) - { - _wat.AppendLine($" ;; Tranceify-Deklaration: {tranceifyDecl.Name}"); - foreach (var member in tranceifyDecl.Members) - { - _wat.AppendLine(" ;; Tranceify-Member"); - } - } - } -} diff --git a/HypnoScript.Compiler/Error/ErrorReporter.cs b/HypnoScript.Compiler/Error/ErrorReporter.cs deleted file mode 100644 index e049b06..0000000 --- a/HypnoScript.Compiler/Error/ErrorReporter.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace HypnoScript.Compiler.Error -{ - public static class ErrorReporter - { - private static readonly List _errors = new(); - - // Runtime-Level: Verwende Fehlercodes und farbliche Logausgaben (z.B. über Console.ForegroundColor) - public static void Report(string message, int line, int column, string errorCode = "E001") - { - _errors.Add(message); - var prevColor = Console.ForegroundColor; - Console.ForegroundColor = ConsoleColor.Red; - Console.Error.WriteLine($"[{errorCode}] Error at {line}:{column} - {message}"); - Console.ForegroundColor = prevColor; - } - - public static IReadOnlyList GetErrors() - { - return _errors.AsReadOnly(); - } - - public static void ClearErrors() - { - _errors.Clear(); - } - - // Eine Erweiterungsmethode zur Abschaltung von Fehlern oder zum Sammeln in einem Log - public static void ReportWarning(string message, int line, int column, string warningCode = "W001") - { - var prevColor = Console.ForegroundColor; - Console.ForegroundColor = ConsoleColor.Yellow; - Console.Error.WriteLine($"[{warningCode}] Warning at {line}:{column} - {message}"); - Console.ForegroundColor = prevColor; - } - } -} diff --git a/HypnoScript.Compiler/HypnoScript.Compiler.csproj b/HypnoScript.Compiler/HypnoScript.Compiler.csproj deleted file mode 100644 index 1c221f5..0000000 --- a/HypnoScript.Compiler/HypnoScript.Compiler.csproj +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - net8.0 - enable - enable - - - diff --git a/HypnoScript.Compiler/Interpreter/HypnoInterpreter.cs b/HypnoScript.Compiler/Interpreter/HypnoInterpreter.cs deleted file mode 100644 index 994d26c..0000000 --- a/HypnoScript.Compiler/Interpreter/HypnoInterpreter.cs +++ /dev/null @@ -1,1397 +0,0 @@ -using HypnoScript.LexerParser.AST; -using HypnoScript.Runtime; -using HypnoScript.Core.Symbols; -using HypnoScript.LexerParser.Parser; -using HypnoScript.Runtime.Builtins; -using System.IO; -using System.Collections.Generic; - -namespace HypnoScript.Compiler.Interpreter -{ - public class BreakException : Exception { } - public class ContinueException : Exception { } - - public partial class HypnoInterpreter - { - private readonly SymbolTable _globals = new(); - private readonly List _assertionFailures = new(); - - private class SinkToLabelException : Exception - { - public string LabelName { get; } - public SinkToLabelException(string labelName) { LabelName = labelName; } - } - - private class ReturnFromFunctionException : Exception - { - public object? Value { get; } - public ReturnFromFunctionException(object? value) { Value = value; } - } - - public void ExecuteProgram(ProgramNode program) - { - // Führe entrance-Block (falls vorhanden) zuerst aus - foreach (var stmt in program.Statements) - { - if (stmt is EntranceBlockNode entrance) - { - ExecuteBlockWithLabels(entrance.Statements); - } - } - // Führe alle anderen Statements aus (außer EntranceBlockNode) - var mainStatements = new List(); - foreach (var stmt in program.Statements) - { - if (stmt is not EntranceBlockNode) - { - mainStatements.Add(stmt); - } - } - ExecuteBlockWithLabels(mainStatements); - } - - private void ExecuteStatement(IStatement stmt) - { - switch (stmt) - { - case VarDeclNode varDecl: - ExecuteVarDecl(varDecl); - break; - case IfStatementNode ifNode: - ExecuteIf(ifNode); - break; - case WhileStatementNode whileNode: - ExecuteWhile(whileNode); - break; - case LoopStatementNode loopNode: - ExecuteLoop(loopNode); - break; - case ObserveStatementNode obs: - var value = EvaluateExpression(obs.Expression); - HypnoBuiltins.Observe(value); - break; - case DriftStatementNode drift: - var ms = EvaluateExpression(drift.Milliseconds); - if (ms is int intMs) - HypnoBuiltins.Drift(intMs); - else if (ms is double doubleMs) - HypnoBuiltins.Drift((int)doubleMs); - else - throw new Exception("drift() expects a number"); - break; - case ReturnStatementNode ret: - if (ret.Expression != null) - throw new ReturnFromFunctionException(EvaluateExpression(ret.Expression)); - else - throw new ReturnFromFunctionException(null); - case ExpressionStatementNode exprStmt: - EvaluateExpression(exprStmt.Expression); - break; - case SnapStatementNode: - throw new BreakException(); - case SinkStatementNode: - throw new ContinueException(); - case SessionDeclNode sessionDecl: - ExecuteSessionDeclaration(sessionDecl); - break; - case TranceifyDeclNode tranceifyDecl: - ExecuteTranceifyDeclaration(tranceifyDecl); - break; - case FunctionDeclNode funcDecl: - ExecuteFunctionDeclaration(funcDecl); - break; - case MindLinkNode mindLink: - ImportMindLink(mindLink.FileName); - break; - case SharedTranceVarDeclNode shared: - object? sharedVal = null; - if (shared.Initializer != null) - sharedVal = EvaluateExpression(shared.Initializer); - var sharedSym = new Symbol(shared.Identifier, shared.TypeName, sharedVal); - if (!_globals.Define(sharedSym)) - Console.Error.WriteLine($"[sharedTrance] Variable '{shared.Identifier}' already defined"); - break; - case LabelNode label: - // Label-Statement selbst tut nichts zur Laufzeit - break; - case SinkToNode sinkTo: - throw new SinkToLabelException(sinkTo.LabelName); - case AssertStatementNode assertStmt: - var cond = EvaluateExpression(assertStmt.Condition); - if (!IsTruthy(cond)) - _assertionFailures.Add(assertStmt.Message ?? "Assertion failed"); - break; - default: - throw new NotSupportedException($"Unsupported statement type: {stmt.GetType().Name}"); - } - } - - private void ExecuteVarDecl(VarDeclNode decl) - { - object? val = null; - if (decl.FromExternal) - { - // Flexible Input-Quelle - var input = HypnoBuiltins.InputProvider($"Input for {decl.Identifier}: "); - val = input; - } - else if (decl.Initializer != null) - { - val = EvaluateExpression(decl.Initializer); - } - - var sym = new Symbol(decl.Identifier, decl.TypeName, val); - if (!_globals.Define(sym)) - { - throw new Exception($"Variable {decl.Identifier} already defined"); - } - } - - private void ExecuteIf(IfStatementNode ifNode) - { - var condValue = EvaluateExpression(ifNode.Condition); - if (IsTruthy(condValue)) - { - foreach (var st in ifNode.ThenBranch) - ExecuteStatement(st); - } - else if (ifNode.ElseBranch != null) - { - foreach (var st in ifNode.ElseBranch) - ExecuteStatement(st); - } - } - - private void ExecuteWhile(WhileStatementNode whileNode) - { - while (true) - { - var cond = EvaluateExpression(whileNode.Condition); - if (!IsTruthy(cond)) break; - - foreach (var st in whileNode.Body) - { - ExecuteStatement(st); - } - } - } - - private void ExecuteLoop(LoopStatementNode loopNode) - { - // Execute initializer - if (loopNode.Initializer != null) - { - ExecuteStatement(loopNode.Initializer); - } - - while (true) - { - var cond = EvaluateExpression(loopNode.Condition); - if (!IsTruthy(cond)) break; - - try - { - foreach (var st in loopNode.Body) - { - ExecuteStatement(st); - } - } - catch (BreakException) - { - break; - } - catch (ContinueException) - { - // Continue - skip to iteration - } - - // Execute iteration - if (loopNode.Iteration != null) - { - ExecuteStatement(loopNode.Iteration); - } - } - } - - private void ExecuteSessionDeclaration(SessionDeclNode sessionDecl) - { - // Store session definition in globals for later instantiation - var sessionSymbol = new Symbol(sessionDecl.Name, "session", sessionDecl); - _globals.Define(sessionSymbol); - } - - private void ExecuteTranceifyDeclaration(TranceifyDeclNode tranceifyDecl) - { - // Store tranceify definition in globals for later instantiation - var tranceifySymbol = new Symbol(tranceifyDecl.Name, "tranceify", tranceifyDecl); - _globals.Define(tranceifySymbol); - } - - private void ExecuteFunctionDeclaration(FunctionDeclNode funcDecl) - { - // Store function definition in globals for later calls - var funcSymbol = new Symbol(funcDecl.Name, "function", funcDecl); - _globals.Define(funcSymbol); - } - - private object? EvaluateExpression(IExpression expr) - { - switch (expr) - { - case LiteralExpressionNode lit: - return ParseLiteral(lit); - case IdentifierExpressionNode id: - var s = _globals.Resolve(id.Name); - if (s == null) throw new Exception($"Unknown identifier {id.Name}"); - return s.Value; - case BinaryExpressionNode bin: - return EvaluateBinary(bin); - case UnaryExpressionNode unary: - return EvaluateUnary(unary); - case ParenthesizedExpressionNode paren: - return EvaluateExpression(paren.Expression); - case AssignmentExpressionNode assign: - return EvaluateAssignment(assign); - case CallExpressionNode call: - return EvaluateCall(call); - case MethodCallExpressionNode methodCall: - return EvaluateMethodCall(methodCall); - case SessionInstantiationNode sessionInst: - return EvaluateSessionInstantiation(sessionInst); - case FieldAccessExpressionNode field: - return EvaluateFieldAccess(field); - case RecordLiteralExpressionNode rec: - return EvaluateRecordLiteral(rec); - case ArrayAccessExpressionNode arrayAccess: - return EvaluateArrayAccess(arrayAccess); - case ArrayLiteralExpressionNode arrayLit: - return EvaluateArrayLiteral(arrayLit); - default: - throw new NotSupportedException($"Unsupported expression type: {expr.GetType().Name}"); - } - } - - private object? ParseLiteral(LiteralExpressionNode lit) - { - if (lit.LiteralType == "number") - { - if (lit.Value.Contains(".")) - return double.Parse(lit.Value); - else - return int.Parse(lit.Value); - } - else if (lit.LiteralType == "boolean") - { - return (lit.Value == "true"); - } - else - { - // string - return lit.Value; - } - } - - private bool IsTruthy(object? val) - { - if (val == null) return false; - if (val is bool b) return b; - // everything else treat as true - return true; - } - - private object? EvaluateBinary(BinaryExpressionNode bin) - { - var leftVal = EvaluateExpression(bin.Left); - var rightVal = EvaluateExpression(bin.Right); - - // Operator-Synonyme unterstützen - switch (bin.Operator) - { - case "+": - // String-Konkatenation oder arithmetische Addition - if (leftVal is string || rightVal is string) - { - return leftVal?.ToString() + rightVal?.ToString(); - } - return Convert.ToDouble(leftVal) + Convert.ToDouble(rightVal); - case "-": - return Convert.ToDouble(leftVal) - Convert.ToDouble(rightVal); - case "*": - return Convert.ToDouble(leftVal) * Convert.ToDouble(rightVal); - case "/": - return Convert.ToDouble(leftVal) / Convert.ToDouble(rightVal); - case ">": - case "lookAtTheWatch": - return Convert.ToDouble(leftVal) > Convert.ToDouble(rightVal); - case "<": - case "fallUnderMySpell": - return Convert.ToDouble(leftVal) < Convert.ToDouble(rightVal); - case ">=": - case "deeplyGreater": - return Convert.ToDouble(leftVal) >= Convert.ToDouble(rightVal); - case "<=": - case "deeplyLess": - return Convert.ToDouble(leftVal) <= Convert.ToDouble(rightVal); - case "==": - case "youAreFeelingVerySleepy": - return Equals(leftVal, rightVal); - case "!=": - case "notSoDeep": - return !Equals(leftVal, rightVal); - default: - throw new Exception($"Unrecognized operator {bin.Operator}"); - } - } - - private object? EvaluateUnary(UnaryExpressionNode unary) - { - var operand = EvaluateExpression(unary.Operand); - switch (unary.Operator) - { - case "-": - return -Convert.ToDouble(operand); - case "+": - return operand; - default: - throw new Exception($"Unrecognized unary operator: {unary.Operator}"); - } - } - - private object? EvaluateAssignment(AssignmentExpressionNode assign) - { - var right = EvaluateExpression(assign.Value); - - // Für einfache Variablenzuweisungen - if (_globals.Resolve(assign.Identifier) != null) - { - // Update existing variable - // Note: This is a simplified implementation - // In a full implementation, we'd need to update the symbol table - return right; - } - - throw new Exception($"Variable '{assign.Identifier}' not defined for assignment"); - } - - private object? EvaluateCall(CallExpressionNode call) - { - // Builtin-Funktionen direkt evaluieren - if (call.Callee is IdentifierExpressionNode id) - { - var functionName = id.Name; - var args = call.Arguments.Select(EvaluateExpression).ToArray(); - - // Erweiterte Builtin-Funktionen - switch (functionName) - { - // Erweiterte hypnotische Funktionen - case "HypnoticBreathing": - if (args.Length >= 1 && args[0] is int cycles) - HypnoBuiltins.HypnoticBreathing(cycles); - else - HypnoBuiltins.HypnoticBreathing(); - return null; - case "HypnoticAnchoring": - if (args.Length >= 1 && args[0] is string anchorStr) - HypnoBuiltins.HypnoticAnchoring(anchorStr); - else - HypnoBuiltins.HypnoticAnchoring(); - return null; - case "HypnoticRegression": - if (args.Length >= 1 && args[0] is int regAge) - HypnoBuiltins.HypnoticRegression(regAge); - else - HypnoBuiltins.HypnoticRegression(); - return null; - case "HypnoticFutureProgression": - if (args.Length >= 1 && args[0] is int futYears) - HypnoBuiltins.HypnoticFutureProgression(futYears); - else - HypnoBuiltins.HypnoticFutureProgression(); - return null; - - // Datei-Operationen - case "FileExists": - if (args.Length >= 1 && args[0] is string filePath1) - return FileBuiltins.FileExists(filePath1); - break; - case "ReadFile": - if (args.Length >= 1 && args[0] is string filePath2) - return FileBuiltins.ReadFile(filePath2); - break; - case "WriteFile": - if (args.Length >= 2 && args[0] is string filePath3 && args[1] is string fileContent3) - FileBuiltins.WriteFile(filePath3, fileContent3); - return null; - case "AppendFile": - if (args.Length >= 2 && args[0] is string filePath4 && args[1] is string fileContent4) - FileBuiltins.AppendFile(filePath4, fileContent4); - return null; - case "ReadLines": - if (args.Length >= 1 && args[0] is string filePath5) - return FileBuiltins.ReadLines(filePath5); - break; - case "WriteLines": - if (args.Length >= 2 && args[0] is string filePath6 && args[1] is string[] fileLines6) - FileBuiltins.WriteLines(filePath6, fileLines6); - return null; - case "GetFileSize": - if (args.Length >= 1 && args[0] is string filePath7) - return FileBuiltins.GetFileSize(filePath7); - break; - case "GetFileExtension": - if (args.Length >= 1 && args[0] is string filePath8) - return FileBuiltins.GetFileExtension(filePath8); - break; - case "GetFileName": - if (args.Length >= 1 && args[0] is string filePath9) - return FileBuiltins.GetFileName(filePath9); - break; - case "GetDirectoryName": - if (args.Length >= 1 && args[0] is string filePath10) - return FileBuiltins.GetDirectoryName(filePath10); - break; - - // Verzeichnis-Operationen - case "DirectoryExists": - if (args.Length >= 1 && args[0] is string dirPath1) - return FileBuiltins.DirectoryExists(dirPath1); - break; - case "CreateDirectory": - if (args.Length >= 1 && args[0] is string dirPath2) - FileBuiltins.CreateDirectory(dirPath2); - return null; - case "GetFiles": - if (args.Length >= 1 && args[0] is string dirPath3) - { - if (args.Length >= 2 && args[1] is string filePattern3) - return FileBuiltins.GetFiles(dirPath3, filePattern3); - else - return FileBuiltins.GetFiles(dirPath3); - } - break; - case "GetDirectories": - if (args.Length >= 1 && args[0] is string dirPath4) - return FileBuiltins.GetDirectories(dirPath4); - break; - - // JSON-Verarbeitung - case "ToJson": - if (args.Length >= 1) - return HypnoBuiltins.ToJson(args[0]); - break; - case "FromJson": - if (args.Length >= 1 && args[0] is string jsonStr) - return HypnoBuiltins.FromJson(jsonStr); - break; - - // Erweiterte mathematische Funktionen - case "Factorial": - if (args.Length >= 1 && args[0] is int factN) - return HypnoBuiltins.Factorial(factN); - break; - case "GCD": - if (args.Length >= 2 && args[0] is double gcdA && args[1] is double gcdB) - return HypnoBuiltins.GCD(gcdA, gcdB); - break; - case "LCM": - if (args.Length >= 2 && args[0] is double lcmA && args[1] is double lcmB) - return HypnoBuiltins.LCM(lcmA, lcmB); - break; - case "DegreesToRadians": - if (args.Length >= 1 && args[0] is double degVal) - return HypnoBuiltins.DegreesToRadians(degVal); - break; - case "RadiansToDegrees": - if (args.Length >= 1 && args[0] is double radVal) - return HypnoBuiltins.RadiansToDegrees(radVal); - break; - case "Asin": - if (args.Length >= 1 && args[0] is double asinX) - return HypnoBuiltins.Asin(asinX); - break; - case "Acos": - if (args.Length >= 1 && args[0] is double acosX) - return HypnoBuiltins.Acos(acosX); - break; - case "Atan": - if (args.Length >= 1 && args[0] is double atanX) - return HypnoBuiltins.Atan(atanX); - break; - case "Atan2": - if (args.Length >= 2 && args[0] is double atan2Y && args[1] is double atan2X) - return HypnoBuiltins.Atan2(atan2Y, atan2X); - break; - - // Erweiterte String-Funktionen - case "Reverse": - if (args.Length >= 1 && args[0] is string revStr) - return HypnoBuiltins.Reverse(revStr); - break; - case "Capitalize": - if (args.Length >= 1 && args[0] is string capStr) - return HypnoBuiltins.Capitalize(capStr); - break; - case "TitleCase": - if (args.Length >= 1 && args[0] is string titleStr) - return HypnoBuiltins.TitleCase(titleStr); - break; - case "CountOccurrences": - if (args.Length >= 2 && args[0] is string countStr && args[1] is string countSub) - return HypnoBuiltins.CountOccurrences(countStr, countSub); - break; - case "RemoveWhitespace": - if (args.Length >= 1 && args[0] is string wsStr) - return HypnoBuiltins.RemoveWhitespace(wsStr); - break; - - // Erweiterte Array-Funktionen - case "ArrayReverse": - if (args.Length >= 1 && args[0] is object[] arrRev) - return HypnoBuiltins.ArrayReverse(arrRev); - break; - case "ArraySort": - if (args.Length >= 1 && args[0] is object[] arrSort) - return HypnoBuiltins.ArraySort(arrSort); - break; - case "ArrayUnique": - if (args.Length >= 1 && args[0] is object[] arrUnique) - return HypnoBuiltins.ArrayUnique(arrUnique); - break; - case "ArrayFilter": - if (args.Length >= 1 && args[0] is object[] arrFilter) - { - // Einfache Implementierung - filtert nach nicht-null Werten - return HypnoBuiltins.ArrayFilter(arrFilter, item => item != null); - } - break; - - // Kryptologische Funktionen - case "HashMD5": - if (args.Length >= 1 && args[0] is string hashInput1) - return HypnoBuiltins.HashMD5(hashInput1); - break; - case "HashSHA256": - if (args.Length >= 1 && args[0] is string hashInput2) - return HypnoBuiltins.HashSHA256(hashInput2); - break; - case "Base64Encode": - if (args.Length >= 1 && args[0] is string base64Input1) - return HypnoBuiltins.Base64Encode(base64Input1); - break; - case "Base64Decode": - if (args.Length >= 1 && args[0] is string base64Input2) - return HypnoBuiltins.Base64Decode(base64Input2); - break; - - // Erweiterte Zeit-Funktionen - case "GetDayOfWeek": - return HypnoBuiltins.GetDayOfWeek(); - case "GetDayOfYear": - return HypnoBuiltins.GetDayOfYear(); - case "IsLeapYear": - if (args.Length >= 1 && args[0] is int leapYear) - return HypnoBuiltins.IsLeapYear(leapYear); - break; - case "GetDaysInMonth": - if (args.Length >= 2 && args[0] is int daysYear && args[1] is int daysMonth) - return HypnoBuiltins.GetDaysInMonth(daysYear, daysMonth); - break; - - // Erweiterte System-Funktionen - case "GetMachineName": - return SystemBuiltins.GetMachineName(); - case "GetUserName": - return SystemBuiltins.GetUserName(); - case "GetOSVersion": - return SystemBuiltins.GetOSVersion(); - case "GetProcessorCount": - return SystemBuiltins.GetProcessorCount(); - case "GetWorkingSet": - return SystemBuiltins.GetWorkingSet(); - case "PlaySound": - if (args.Length >= 2 && args[0] is int sndFreq && args[1] is int sndDur) - SystemBuiltins.PlaySound(sndFreq, sndDur); - else - SystemBuiltins.PlaySound(); - return null; - case "Vibrate": - if (args.Length >= 1 && args[0] is int vibDur) - SystemBuiltins.Vibrate(vibDur); - else - SystemBuiltins.Vibrate(); - return null; - - // Erweiterte Debugging-Funktionen - case "DebugPrint": - if (args.Length >= 1) - HypnoBuiltins.DebugPrint(args[0]); - return null; - case "DebugPrintType": - if (args.Length >= 1) - HypnoBuiltins.DebugPrintType(args[0]); - return null; - case "DebugPrintMemory": - HypnoBuiltins.DebugPrintMemory(); - return null; - case "DebugPrintStackTrace": - HypnoBuiltins.DebugPrintStackTrace(); - return null; - - // Array-Funktionen - case "ArrayLength": - if (args.Length >= 1 && args[0] is object[] arrLen) - return ArrayBuiltins.ArrayLength(arrLen); - break; - case "ArrayGet": - if (args.Length >= 2 && args[0] is object[] arrGet && args[1] is int indexGet) - return ArrayBuiltins.ArrayGet(arrGet, indexGet); - break; - case "ArraySet": - if (args.Length >= 3 && args[0] is object[] arrSet && args[1] is int indexSet) - { - ArrayBuiltins.ArraySet(arrSet, indexSet, args[2] ?? new object()); - return null; - } - break; - case "ArraySlice": - if (args.Length >= 3 && args[0] is object[] arrSlice && args[1] is int startSlice && args[2] is int length) - return ArrayBuiltins.ArraySlice(arrSlice, startSlice, length); - break; - case "ArrayConcat": - if (args.Length >= 2 && args[0] is object[] arr1 && args[1] is object[] arr2) - return ArrayBuiltins.ArrayConcat(arr1, arr2); - break; - case "ArrayIndexOf": - if (args.Length >= 2 && args[0] is object[] arrIdx) - return ArrayBuiltins.ArrayIndexOf(arrIdx, args[1] ?? new object()); - break; - case "ArrayContains": - if (args.Length >= 2 && args[0] is object[] arrCont) - return ArrayBuiltins.ArrayContains(arrCont, args[1] ?? new object()); - break; - case "ArrayMap": - if (args.Length >= 1 && args[0] is object[] arrMap) - return ArrayBuiltins.ArrayMap(arrMap, item => item); // Einfache Implementierung - break; - case "ArrayReduce": - if (args.Length >= 2 && args[0] is object[] arrRed) - return ArrayBuiltins.ArrayReduce(arrRed, (acc, item) => item, args[1] ?? new object()); - break; - case "ArrayFlatten": - if (args.Length >= 1 && args[0] is object[] arrFlat) - return ArrayBuiltins.ArrayFlatten(arrFlat); - break; - - // Mathematische Funktionen - case "Abs": - if (args.Length >= 1 && args[0] is double absVal) - return MathBuiltins.Abs(absVal); - break; - case "Sin": - if (args.Length >= 1 && args[0] is double sinVal) - return MathBuiltins.Sin(sinVal); - break; - case "Cos": - if (args.Length >= 1 && args[0] is double cosVal) - return MathBuiltins.Cos(cosVal); - break; - case "Tan": - if (args.Length >= 1 && args[0] is double tanVal) - return MathBuiltins.Tan(tanVal); - break; - case "Sqrt": - if (args.Length >= 1 && args[0] is double sqrtVal) - return MathBuiltins.Sqrt(sqrtVal); - break; - case "Pow": - if (args.Length >= 2 && args[0] is double powX && args[1] is double powY) - return MathBuiltins.Pow(powX, powY); - break; - case "Floor": - if (args.Length >= 1 && args[0] is double floorVal) - return MathBuiltins.Floor(floorVal); - break; - case "Ceiling": - if (args.Length >= 1 && args[0] is double ceilVal) - return MathBuiltins.Ceiling(ceilVal); - break; - case "Round": - if (args.Length >= 1 && args[0] is double roundVal) - return MathBuiltins.Round(roundVal); - break; - case "Log": - if (args.Length >= 1 && args[0] is double logVal) - return MathBuiltins.Log(logVal); - break; - case "Log10": - if (args.Length >= 1 && args[0] is double log10Val) - return MathBuiltins.Log10(log10Val); - break; - case "Exp": - if (args.Length >= 1 && args[0] is double expVal) - return MathBuiltins.Exp(expVal); - break; - case "Max": - if (args.Length >= 2 && args[0] is double maxX && args[1] is double maxY) - return MathBuiltins.Max(maxX, maxY); - break; - case "Min": - if (args.Length >= 2 && args[0] is double minX && args[1] is double minY) - return MathBuiltins.Min(minX, minY); - break; - case "Random": - return MathBuiltins.Random(); - case "RandomInt": - if (args.Length >= 2 && args[0] is int randMin && args[1] is int randMax) - return MathBuiltins.RandomInt(randMin, randMax); - break; - - // String-Funktionen - case "Length": - if (args.Length >= 1 && args[0] is string lenStr) - return StringBuiltins.Length(lenStr); - break; - case "Substring": - if (args.Length >= 3 && args[0] is string subStr && args[1] is int subStart && args[2] is int subLen) - return StringBuiltins.Substring(subStr, subStart, subLen); - break; - case "ToUpper": - if (args.Length >= 1 && args[0] is string upperStr) - return StringBuiltins.ToUpper(upperStr); - break; - case "ToLower": - if (args.Length >= 1 && args[0] is string lowerStr) - return StringBuiltins.ToLower(lowerStr); - break; - case "Contains": - if (args.Length >= 2 && args[0] is string contStr && args[1] is string contSub) - return StringBuiltins.Contains(contStr, contSub); - break; - case "Replace": - if (args.Length >= 3 && args[0] is string repStrReplace && args[1] is string repOld && args[2] is string repNew) - return StringBuiltins.Replace(repStrReplace, repOld, repNew); - break; - case "Trim": - if (args.Length >= 1 && args[0] is string trimStr) - return StringBuiltins.Trim(trimStr); - break; - case "IndexOf": - if (args.Length >= 2 && args[0] is string idxStr && args[1] is string idxSub) - return StringBuiltins.IndexOf(idxStr, idxSub); - break; - case "Split": - if (args.Length >= 2 && args[0] is string splitStr && args[1] is string splitSep) - return StringBuiltins.Split(splitStr, splitSep); - break; - case "Join": - if (args.Length >= 2 && args[0] is string[] joinArr && args[1] is string joinSep) - return StringBuiltins.Join(joinArr, joinSep); - break; - - // Konvertierungsfunktionen - case "ToInt": - if (args.Length >= 1) - return HypnoBuiltins.ToInt(args[0]); - break; - case "ToDouble": - if (args.Length >= 1) - return HypnoBuiltins.ToDouble(args[0]); - break; - case "ToString": - if (args.Length >= 1) - return HypnoBuiltins.ToString(args[0]); - break; - case "ToBoolean": - if (args.Length >= 1) - return HypnoBuiltins.ToBoolean(args[0]); - break; - - // Zeit- und Datumsfunktionen - case "GetCurrentTime": - return HypnoBuiltins.GetCurrentTime(); - case "GetCurrentDate": - return HypnoBuiltins.GetCurrentDate(); - case "GetCurrentTimeString": - return HypnoBuiltins.GetCurrentTimeString(); - case "GetCurrentDateTime": - return HypnoBuiltins.GetCurrentDateTime(); - - // System-Funktionen - case "ClearScreen": - SystemBuiltins.ClearScreen(); - return null; - case "Beep": - if (args.Length >= 2 && args[0] is int beepFreq && args[1] is int beepDur) - SystemBuiltins.Beep(beepFreq, beepDur); - else - SystemBuiltins.Beep(); - return null; - case "GetEnvironmentVariable": - if (args.Length >= 1 && args[0] is string envVar) - return SystemBuiltins.GetEnvironmentVariable(envVar); - break; - - // Utility-Funktionen - case "IsValidEmail": - if (args.Length >= 1 && args[0] is string email) - return NetworkBuiltins.IsValidEmail(email); - break; - case "IsValidUrl": - if (args.Length >= 1 && args[0] is string url) - return NetworkBuiltins.IsValidUrl(url); - break; - case "IsValidJson": - if (args.Length >= 1 && args[0] is string json) - return HypnoBuiltins.IsValidJson(json); - break; - case "FormatNumber": - if (args.Length >= 2 && args[0] is double num && args[1] is int dec) - return HypnoBuiltins.FormatNumber(num, dec); - else if (args.Length >= 1 && args[0] is double num2) - return HypnoBuiltins.FormatNumber(num2); - break; - case "FormatCurrency": - if (args.Length >= 2 && args[0] is double curr && args[1] is string currency) - return HypnoBuiltins.FormatCurrency(curr, currency); - else if (args.Length >= 1 && args[0] is double curr2) - return HypnoBuiltins.FormatCurrency(curr2); - break; - case "FormatPercentage": - if (args.Length >= 1 && args[0] is double perc) - return HypnoBuiltins.FormatPercentage(perc); - break; - - // HTTP-Funktionen - case "HttpGet": - if (args.Length >= 1 && args[0] is string httpUrl) - return NetworkBuiltins.HttpGet(httpUrl); - break; - case "HttpPost": - if (args.Length >= 2 && args[0] is string postUrl && args[1] is string postData) - return NetworkBuiltins.HttpPost(postUrl, postData); - break; - - // Statistik-Funktionen - case "CalculateMean": - if (args.Length >= 1 && args[0] is object[] meanArr) - return HypnoBuiltins.CalculateMean(meanArr); - break; - case "CalculateStandardDeviation": - if (args.Length >= 1 && args[0] is object[] stdArr) - return HypnoBuiltins.CalculateStandardDeviation(stdArr); - break; - case "LinearRegression": - if (args.Length >= 2 && args[0] is object[] lrX && args[1] is object[] lrY) - return HypnoBuiltins.LinearRegression(lrX, lrY); - break; - - // Performance-Funktionen - case "GetPerformanceMetrics": - return HypnoBuiltins.GetPerformanceMetrics(); - - // Hypnotische Spezialfunktionen - case "DeepTrance": - if (args.Length >= 1 && args[0] is int deepDur) - HypnoBuiltins.DeepTrance(deepDur); - else - HypnoBuiltins.DeepTrance(); - return null; - case "HypnoticCountdown": - if (args.Length >= 1 && args[0] is int countFrom) - HypnoBuiltins.HypnoticCountdown(countFrom); - else - HypnoBuiltins.HypnoticCountdown(); - return null; - case "TranceInduction": - if (args.Length >= 1 && args[0] is string subject) - HypnoBuiltins.TranceInduction(subject); - else - HypnoBuiltins.TranceInduction(); - return null; - case "HypnoticVisualization": - if (args.Length >= 1 && args[0] is string scene) - HypnoBuiltins.HypnoticVisualization(scene); - else - HypnoBuiltins.HypnoticVisualization(); - return null; - case "ProgressiveRelaxation": - if (args.Length >= 1 && args[0] is int steps) - HypnoBuiltins.ProgressiveRelaxation(steps); - else - HypnoBuiltins.ProgressiveRelaxation(); - return null; - case "HypnoticSuggestion": - if (args.Length >= 1 && args[0] is string suggestion) - HypnoBuiltins.HypnoticSuggestion(suggestion); - return null; - case "TranceDeepening": - if (args.Length >= 1 && args[0] is int levels) - HypnoBuiltins.TranceDeepening(levels); - else - HypnoBuiltins.TranceDeepening(); - return null; - case "HypnoticPatternMatching": - if (args.Length >= 1 && args[0] is string pattern) - HypnoBuiltins.HypnoticPatternMatching(pattern); - return null; - case "HypnoticTimeDilation": - if (args.Length >= 1 && args[0] is double factor) - HypnoBuiltins.HypnoticTimeDilation(factor); - else - HypnoBuiltins.HypnoticTimeDilation(); - return null; - case "HypnoticMemoryEnhancement": - HypnoBuiltins.HypnoticMemoryEnhancement(); - return null; - case "HypnoticCreativityBoost": - HypnoBuiltins.HypnoticCreativityBoost(); - return null; - - // Weitere Utility-Funktionen - case "Clamp": - if (args.Length >= 3 && args[0] is double val && args[1] is double min && args[2] is double max) - return HypnoBuiltins.Clamp(val, min, max); - break; - case "Sign": - if (args.Length >= 1 && args[0] is double signVal) - return HypnoBuiltins.Sign(signVal); - break; - case "IsEven": - if (args.Length >= 1 && args[0] is int evenVal) - return HypnoBuiltins.IsEven(evenVal); - break; - case "IsOdd": - if (args.Length >= 1 && args[0] is int oddVal) - return HypnoBuiltins.IsOdd(oddVal); - break; - case "ShuffleArray": - if (args.Length >= 1 && args[0] is object[] arrShuf) - return HypnoBuiltins.ShuffleArray(arrShuf); - break; - case "SumArray": - if (args.Length >= 1 && args[0] is object[] arrSum) - return HypnoBuiltins.SumArray(arrSum); - break; - case "AverageArray": - if (args.Length >= 1 && args[0] is object[] arrAvg) - return HypnoBuiltins.AverageArray(arrAvg); - break; - case "Range": - if (args.Length >= 2 && args[0] is int startRange && args[1] is int count) - return HypnoBuiltins.Range(startRange, count); - break; - case "Repeat": - if (args.Length >= 2 && args[1] is int repCount) - return HypnoBuiltins.Repeat(args[0] ?? "", repCount); - break; - case "Swap": - if (args.Length >= 3 && args[0] is object[] arrSwap && args[1] is int i && args[2] is int j) - { - HypnoBuiltins.Swap(arrSwap, i, j); - return null; - } - break; - case "ChunkArray": - if (args.Length >= 2 && args[0] is object[] arrChunk && args[1] is int chunkSize) - return HypnoBuiltins.ChunkArray(arrChunk, chunkSize); - break; - case "ArraySum": - if (args.Length >= 1 && args[0] is object[] arrSum2) - return HypnoBuiltins.ArraySum(arrSum2); - break; - case "ArrayMin": - if (args.Length >= 1 && args[0] is object[] arrMin) - return HypnoBuiltins.ArrayMin(arrMin); - break; - case "ArrayMax": - if (args.Length >= 1 && args[0] is object[] arrMax) - return HypnoBuiltins.ArrayMax(arrMax); - break; - case "ArrayCount": - if (args.Length >= 2 && args[0] is object[] arrCount) - return HypnoBuiltins.ArrayCount(arrCount, args[1]); - break; - case "ArrayRemove": - if (args.Length >= 2 && args[0] is object[] arrRem) - return HypnoBuiltins.ArrayRemove(arrRem, args[1]); - break; - case "ArrayDistinct": - if (args.Length >= 1 && args[0] is object[] arrDist) - return HypnoBuiltins.ArrayDistinct(arrDist); - break; - case "IsNullOrEmpty": - if (args.Length >= 1) - return HypnoBuiltins.IsNullOrEmpty(args[0]?.ToString()); - break; - case "RepeatString": - if (args.Length >= 2 && args[0] is string repStrRepeat && args[1] is int repN) - return HypnoBuiltins.RepeatString(repStrRepeat, repN); - break; - case "ReverseWords": - if (args.Length >= 1 && args[0] is string revWords) - return HypnoBuiltins.ReverseWords(revWords); - break; - case "Truncate": - if (args.Length >= 2 && args[0] is string truncStr && args[1] is int truncLen) - return HypnoBuiltins.Truncate(truncStr, truncLen); - break; - case "RemoveDigits": - if (args.Length >= 1 && args[0] is string remDig) - return HypnoBuiltins.RemoveDigits(remDig); - break; - case "IsPrime": - if (args.Length >= 1 && args[0] is int nPrime) - return HypnoBuiltins.IsPrime(nPrime); - break; - case "FactorialBig": - if (args.Length >= 1 && args[0] is int nFact) - return HypnoBuiltins.FactorialBig(nFact); - break; - case "ToHex": - if (args.Length >= 1 && args[0] is long nHex) - return HypnoBuiltins.ToHex(nHex); - break; - case "ToBinary": - if (args.Length >= 1 && args[0] is long nBin) - return HypnoBuiltins.ToBinary(nBin); - break; - case "ParseInt": - if (args.Length >= 1 && args[0] is string strInt) - return HypnoBuiltins.ParseInt(strInt); - break; - case "GetEnvVars": - return HypnoBuiltins.GetEnvVars(); - case "GetTempPath": - return HypnoBuiltins.GetTempPath(); - case "GetTickCount": - return HypnoBuiltins.GetTickCount(); - case "Sleep": - if (args.Length >= 1 && args[0] is int ms) - { - HypnoBuiltins.Sleep(ms); - return null; - } - break; - case "AddDays": - if (args.Length >= 2 && args[0] is string date1 && args[1] is int days1) - return HypnoBuiltins.AddDays(date1, days1); - break; - case "AddMonths": - if (args.Length >= 2 && args[0] is string date2 && args[1] is int months) - return HypnoBuiltins.AddMonths(date2, months); - break; - case "AddYears": - if (args.Length >= 2 && args[0] is string date3 && args[1] is int years) - return HypnoBuiltins.AddYears(date3, years); - break; - case "ParseDate": - if (args.Length >= 1 && args[0] is string dateStr) - return HypnoBuiltins.ParseDate(dateStr); - break; - case "IsArray": - if (args.Length >= 1) - return HypnoBuiltins.IsArray(args[0]); - break; - case "IsNumber": - if (args.Length >= 1) - return HypnoBuiltins.IsNumber(args[0]); - break; - case "IsString": - if (args.Length >= 1) - return HypnoBuiltins.IsString(args[0]); - break; - case "IsBoolean": - if (args.Length >= 1) - return HypnoBuiltins.IsBoolean(args[0]); - break; - - // Dictionary-Utilities - case "CreateDictionary": - return HypnoBuiltins.CreateDictionary(); - case "DictionaryKeys": - if (args.Length >= 1 && args[0] is Dictionary dictKeys) - return HypnoBuiltins.DictionaryKeys(dictKeys); - break; - case "DictionaryValues": - if (args.Length >= 1 && args[0] is Dictionary dictValues) - return HypnoBuiltins.DictionaryValues(dictValues); - break; - case "DictionaryContainsKey": - if (args.Length >= 2 && args[0] is Dictionary dictCont && args[1] is string key) - return HypnoBuiltins.DictionaryContainsKey(dictCont, key); - break; - case "DictionaryGet": - if (args.Length >= 2 && args[0] is Dictionary dictGet && args[1] is string keyGet) - { - var defaultValue = args.Length >= 3 ? args[2] : null; - return HypnoBuiltins.DictionaryGet(dictGet, keyGet, defaultValue); - } - break; - case "DictionarySet": - if (args.Length >= 3 && args[0] is Dictionary dictSet && args[1] is string keySet) - { - HypnoBuiltins.DictionarySet(dictSet, keySet, args[2] ?? ""); - return null; - } - break; - case "DictionaryRemove": - if (args.Length >= 2 && args[0] is Dictionary dictRem && args[1] is string keyRem) - return HypnoBuiltins.DictionaryRemove(dictRem, keyRem); - break; - case "DictionaryCount": - if (args.Length >= 1 && args[0] is Dictionary dictCount) - return HypnoBuiltins.DictionaryCount(dictCount); - break; - - // Erweiterte String-Utilities - case "StartsWith": - if (args.Length >= 2 && args[0] is string strStart && args[1] is string prefix) - return StringBuiltins.StartsWith(strStart, prefix); - break; - case "EndsWith": - if (args.Length >= 2 && args[0] is string strEnd && args[1] is string suffix) - return StringBuiltins.EndsWith(strEnd, suffix); - break; - case "PadLeft": - if (args.Length >= 2 && args[0] is string strPadL && args[1] is int widthL) - { - var charL = args.Length >= 3 && args[2] is char cL ? cL : ' '; - return StringBuiltins.PadLeft(strPadL, widthL, charL); - } - break; - case "PadRight": - if (args.Length >= 2 && args[0] is string strPadR && args[1] is int widthR) - { - var charR = args.Length >= 3 && args[2] is char cR ? cR : ' '; - return StringBuiltins.PadRight(strPadR, widthR, charR); - } - break; - case "Insert": - if (args.Length >= 3 && args[0] is string strIns && args[1] is int indexIns && args[2] is string valueIns) - return StringBuiltins.Insert(strIns, indexIns, valueIns); - break; - case "Remove": - if (args.Length >= 3 && args[0] is string strRem && args[1] is int startRem && args[2] is int countRem) - return StringBuiltins.Remove(strRem, startRem, countRem); - break; - case "Compare": - if (args.Length >= 2 && args[0] is string str1 && args[1] is string str2) - return StringBuiltins.Compare(str1, str2); - break; - case "EqualsIgnoreCase": - if (args.Length >= 2 && args[0] is string strEq1 && args[1] is string strEq2) - return StringBuiltins.EqualsIgnoreCase(strEq1, strEq2); - break; - case "IsPalindrome": - if (args.Length >= 1 && args[0] is string strPal) - return StringBuiltins.IsPalindrome(strPal); - break; - case "CountWords": - if (args.Length >= 1 && args[0] is string strWords) - return StringBuiltins.CountWords(strWords); - break; - case "ExtractNumbers": - if (args.Length >= 1 && args[0] is string strNum) - return StringBuiltins.ExtractNumbers(strNum); - break; - case "ExtractLetters": - if (args.Length >= 1 && args[0] is string strLet) - return StringBuiltins.ExtractLetters(strLet); - break; - } - } - - // Fallback für andere Funktionen - var callee = EvaluateExpression(call.Callee); - if (callee is not FunctionDeclNode func) - { - throw new Exception($"Cannot call non-function: {callee}"); - } - - // Funktionsaufruf-Logik mit Rückgabewert - var localScope = new SymbolTable(_globals); - for (int i = 0; i < func.Parameters.Count; i++) - { - var param = func.Parameters[i]; - var argValue = i < call.Arguments.Count ? EvaluateExpression(call.Arguments[i]) : null; - localScope.Define(new Symbol(param.Name, param.TypeName, argValue)); - } - - try - { - foreach (var stmt in func.Body) - { - if (stmt is ReturnStatementNode ret) - { - if (ret.Expression != null) - return EvaluateExpression(ret.Expression); - else - return null; - } - ExecuteStatement(stmt); - } - } - catch (ReturnFromFunctionException ex) - { - return ex.Value; - } - return null; - } - - private object? EvaluateMethodCall(MethodCallExpressionNode methodCall) - { - var target = EvaluateExpression(methodCall.Target); - - if (target is SessionInstance session) - { - // Methodenaufruf auf Session-Instanz - var arguments = new List(); - foreach (var arg in methodCall.Arguments) - { - arguments.Add(EvaluateExpression(arg)); - } - return EvaluateSessionMemberCall(session, methodCall.MethodName, arguments); - } - - throw new Exception($"Method call on non-session value: {methodCall.MethodName}"); - } - - private object? EvaluateSessionInstantiation(SessionInstantiationNode sessionInst) - { - // Session-Instanz erstellen - var sessionSymbol = _globals.Resolve(sessionInst.SessionName); - if (sessionSymbol?.Value is SessionDeclNode sessionDecl) - { - var arguments = new List(); - foreach (var arg in sessionInst.Arguments) - { - arguments.Add(EvaluateExpression(arg)); - } - return InstantiateSession(sessionDecl, arguments); - } - - throw new Exception($"Session '{sessionInst.SessionName}' not found"); - } - - private object? EvaluateFieldAccess(FieldAccessExpressionNode field) - { - var target = EvaluateExpression(field.Target); - if (target is Dictionary recordDict) - { - if (recordDict.TryGetValue(field.FieldName, out var value)) - return value; - throw new Exception($"Field '{field.FieldName}' not found in record."); - } - if (target is SessionInstance session) - { - if (session.Fields.TryGetValue(field.FieldName, out var value)) - return value; - throw new Exception($"Field '{field.FieldName}' not found in session '{session.Name}'."); - } - throw new Exception($"Field access on non-record/session value: {field.FieldName}"); - } - - private object? EvaluateRecordLiteral(RecordLiteralExpressionNode rec) - { - var dict = new Dictionary(); - foreach (var kv in rec.Fields) - { - dict[kv.Key] = EvaluateExpression(kv.Value); - } - // Optional: dict["__type"] = rec.TypeName; - return dict; - } - - private object? EvaluateArrayAccess(ArrayAccessExpressionNode arrayAccess) - { - var array = EvaluateExpression(arrayAccess.Array); - var index = EvaluateExpression(arrayAccess.Index); - - if (array is List list && index is int intIndex) - { - if (intIndex >= 0 && intIndex < list.Count) - return list[intIndex]; - throw new Exception($"Array index {intIndex} out of bounds (array length: {list.Count})"); - } - - throw new Exception("Array access requires a list and integer index"); - } - - private object? EvaluateArrayLiteral(ArrayLiteralExpressionNode arrayLit) - { - var elements = new List(); - foreach (var element in arrayLit.Elements) - { - elements.Add(EvaluateExpression(element)); - } - return elements; - } - - private void ImportMindLink(string fileName) - { - // Annahme: relativer Pfad, .hyp-Datei - if (!File.Exists(fileName)) - { - Console.Error.WriteLine($"[mindLink] File not found: {fileName}"); - return; - } - var code = File.ReadAllText(fileName); - var lexer = new HypnoScript.LexerParser.Lexer.HypnoLexer(code); - var tokens = lexer.Lex(); - var parser = new HypnoParser(tokens); - var importedProgram = parser.ParseProgram(); - // Übernehme nur globale Definitionen - foreach (var stmt in importedProgram.Statements) - { - switch (stmt) - { - case SessionDeclNode session: - _globals.Define(new HypnoScript.Core.Symbols.Symbol(session.Name, "session", session)); - break; - case TranceifyDeclNode trance: - _globals.Define(new HypnoScript.Core.Symbols.Symbol(trance.Name, "tranceify", trance)); - break; - case FunctionDeclNode func: - _globals.Define(new HypnoScript.Core.Symbols.Symbol(func.Name, func.ReturnType, func)); - break; - case VarDeclNode varDecl: - _globals.Define(new HypnoScript.Core.Symbols.Symbol(varDecl.Identifier, varDecl.TypeName)); - break; - } - } - } - - private void ExecuteBlockWithLabels(List statements) - { - // Mappe Labelnamen auf Statement-Index - var labelMap = new Dictionary(); - for (int i = 0; i < statements.Count; i++) - { - if (statements[i] is HypnoScript.LexerParser.AST.LabelNode label) - labelMap[label.Name] = i; - } - for (int i = 0; i < statements.Count; i++) - { - try - { - ExecuteStatement(statements[i]); - } - catch (SinkToLabelException ex) - { - if (labelMap.TryGetValue(ex.LabelName, out var targetIdx)) - { - i = targetIdx - 1; // -1, da i++ im Loop - continue; - } - else - { - throw; // Label nicht im Block gefunden -> Exception weiterwerfen - } - } - } - } - - public IReadOnlyList GetAssertionFailures() => _assertionFailures.AsReadOnly(); - } -} diff --git a/HypnoScript.Compiler/Interpreter/SessionInstance.cs b/HypnoScript.Compiler/Interpreter/SessionInstance.cs deleted file mode 100644 index fc9e4bc..0000000 --- a/HypnoScript.Compiler/Interpreter/SessionInstance.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Collections.Generic; -using HypnoScript.LexerParser.AST; - -namespace HypnoScript.Compiler.Interpreter -{ - // Repräsentiert eine Instanz einer Session (ähnlich einer Klasse) - public class SessionInstance(string name) - { - public string Name { get; set; } = name; - public Dictionary Fields { get; } = []; - public Dictionary Methods { get; } = []; - } -} diff --git a/HypnoScript.Compiler/Interpreter/SessionInterpreter.cs b/HypnoScript.Compiler/Interpreter/SessionInterpreter.cs deleted file mode 100644 index 9ba93ce..0000000 --- a/HypnoScript.Compiler/Interpreter/SessionInterpreter.cs +++ /dev/null @@ -1,78 +0,0 @@ -using System; -using System.Collections.Generic; -using HypnoScript.LexerParser.AST; -using HypnoScript.Core.Symbols; - -namespace HypnoScript.Compiler.Interpreter -{ - public partial class HypnoInterpreter - { - // Erzeugt eine Session-Instanz basierend auf einer SessionDeclNode und übergibt die Argumente an den Konstruktor. - private SessionInstance InstantiateSession(SessionDeclNode sessionDecl, List constructorArgs) - { - var instance = new SessionInstance(sessionDecl.Name); - - // Initialisierung der Felder und Registrierung von Methoden. - foreach (var member in sessionDecl.Members) - { - if (member is SessionMemberNode smVar && smVar.Declaration is VarDeclNode v) - { - // Setze das Feld auf den Wert des Initializers (falls vorhanden) oder auf null. - instance.Fields[v.Identifier] = v.Initializer != null ? EvaluateExpression(v.Initializer) : null; - } - else if (member is SessionMemberNode smFunc && smFunc.Declaration is FunctionDeclNode f) - { - if (f.Name != "constructor") - { - instance.Methods[f.Name] = f; - } - // Den Konstruktor behandeln wir später. - } - } - - // Falls ein Konstruktor definiert ist, führe ihn aus. - var constructorMember = sessionDecl.Members.Find(m => m is SessionMemberNode sm && sm.Declaration is FunctionDeclNode fd && fd.Name == "constructor") as SessionMemberNode; - var constructor = constructorMember?.Declaration as FunctionDeclNode; - if (constructor != null) - { - // Erstelle einen separaten Scope für den Konstruktor. - var localScope = new SymbolTable(_globals); - for (int i = 0; i < constructor.Parameters.Count; i++) - { - var param = constructor.Parameters[i]; - var argValue = i < constructorArgs.Count ? constructorArgs[i] : null; - localScope.Define(new Symbol(param.Name, param.TypeName, argValue)); - } - // Führe den Konstruktor-Body aus. (Rückgabewert wird ignoriert.) - foreach (var stmt in constructor.Body) - { - ExecuteStatement(stmt); - } - } - return instance; - } - - // Führt einen Methodenaufruf auf einer Session-Instanz aus. - private object? EvaluateSessionMemberCall(SessionInstance instance, string memberName, List arguments) - { - if (instance.Methods.TryGetValue(memberName, out var method)) - { - // Erstelle einen neuen Scope für den Methodenaufruf und binde Parameter. - var localScope = new SymbolTable(_globals); - for (int i = 0; i < method.Parameters.Count; i++) - { - var param = method.Parameters[i]; - var argValue = i < arguments.Count ? arguments[i] : null; - localScope.Define(new Symbol(param.Name, param.TypeName, argValue)); - } - // Führe den Methoden-Body aus. - foreach (var stmt in method.Body) - { - ExecuteStatement(stmt); - } - return null; // Rückgabewert ignoriert – Erweiterungen möglich. - } - throw new Exception($"Member '{memberName}' nicht in Session '{instance.Name}' gefunden."); - } - } -} diff --git a/HypnoScript.Compiler/Session/SessionFactory.cs b/HypnoScript.Compiler/Session/SessionFactory.cs deleted file mode 100644 index a0db8bf..0000000 --- a/HypnoScript.Compiler/Session/SessionFactory.cs +++ /dev/null @@ -1,330 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using HypnoScript.LexerParser.AST; -using HypnoScript.Core.Symbols; -using HypnoScript.Core.Types; - -namespace HypnoScript.Compiler.Session -{ - /// - /// Factory for creating and managing Session instances. - /// - public static class SessionFactory - { - private static readonly Dictionary _sessionTemplates = new(); - private static readonly Dictionary _activeSessions = new(); - - /// - /// Registers a session template for later instantiation. - /// - /// The name of the session template - /// The session template - public static void RegisterSessionTemplate(string name, SessionTemplate template) - { - _sessionTemplates[name] = template; - } - - /// - /// Creates a new session instance from a template. - /// - /// The name of the template to use - /// The name for the new session instance - /// The created session instance - public static SessionInstance CreateSession(string templateName, string sessionName) - { - if (!_sessionTemplates.TryGetValue(templateName, out var template)) - { - throw new ArgumentException($"Session template '{templateName}' not found."); - } - - var session = new SessionInstance(sessionName, template); - _activeSessions[sessionName] = session; - return session; - } - - /// - /// Creates a session instance directly from a SessionDeclNode. - /// - /// The session declaration node - /// The created session instance - public static SessionInstance CreateSessionFromDeclaration(SessionDeclNode sessionDecl) - { - var template = new SessionTemplate(sessionDecl.Name, sessionDecl.Members); - var session = new SessionInstance(sessionDecl.Name, template); - _activeSessions[sessionDecl.Name] = session; - return session; - } - - /// - /// Gets an active session by name. - /// - /// The name of the session - /// The session instance or null if not found - public static SessionInstance? GetSession(string sessionName) - { - return _activeSessions.TryGetValue(sessionName, out var session) ? session : null; - } - - /// - /// Removes a session instance. - /// - /// The name of the session to remove - /// True if the session was removed, false if not found - public static bool RemoveSession(string sessionName) - { - return _activeSessions.Remove(sessionName); - } - - /// - /// Gets all active session names. - /// - /// Array of active session names - public static string[] GetActiveSessionNames() - { - return _activeSessions.Keys.ToArray(); - } - - /// - /// Gets all registered template names. - /// - /// Array of registered template names - public static string[] GetRegisteredTemplateNames() - { - return _sessionTemplates.Keys.ToArray(); - } - - /// - /// Clears all active sessions. - /// - public static void ClearAllSessions() - { - _activeSessions.Clear(); - } - - /// - /// Validates a session declaration for type consistency. - /// - /// The session declaration to validate - /// Validation result with any errors - public static ValidationResult ValidateSessionDeclaration(SessionDeclNode sessionDecl) - { - var result = new ValidationResult(); - var symbolTable = new SymbolTable(); - - foreach (var member in sessionDecl.Members) - { - try - { - // Validate member type - if (member.Declaration is VarDeclNode varDecl) - { - if (!string.IsNullOrEmpty(varDecl.TypeName)) - { - // Note: HypnoType.FromString doesn't exist, so we'll skip type validation for now - // var type = HypnoType.FromString(varDecl.TypeName); - // if (type == null) - // { - // result.AddError($"Unknown type '{varDecl.TypeName}' for variable '{varDecl.Identifier}'"); - // } - } - - // Check for duplicate variable names - if (symbolTable.HasSymbol(varDecl.Identifier)) - { - result.AddError($"Duplicate variable name '{varDecl.Identifier}' in session '{sessionDecl.Name}'"); - } - else - { - var symbol = new Symbol(varDecl.Identifier, varDecl.TypeName ?? "any"); - symbolTable.Define(symbol); - } - } - else if (member.Declaration is FunctionDeclNode funcDecl) - { - // Check for duplicate function names - if (symbolTable.HasSymbol(funcDecl.Name)) - { - result.AddError($"Duplicate function name '{funcDecl.Name}' in session '{sessionDecl.Name}'"); - } - else - { - var symbol = new Symbol(funcDecl.Name, "function"); - symbolTable.Define(symbol); - } - } - } - catch (Exception ex) - { - result.AddError($"Error validating session member: {ex.Message}"); - } - } - - return result; - } - } - - /// - /// Template for creating session instances. - /// - public class SessionTemplate - { - /// - /// The name of the session template. - /// - public string Name { get; } - - /// - /// The members of the session. - /// - public List Members { get; } - - /// - /// Initializes a new session template. - /// - /// The name of the template - /// The session members - public SessionTemplate(string name, List members) - { - Name = name; - Members = members ?? new List(); - } - } - - /// - /// Represents a session instance. - /// - public class SessionInstance - { - /// - /// The name of the session instance. - /// - public string Name { get; } - - /// - /// The template used to create this session. - /// - public SessionTemplate Template { get; } - - /// - /// The symbol table for this session. - /// - public SymbolTable SymbolTable { get; } - - /// - /// The variables in this session. - /// - public Dictionary Variables { get; } - - /// - /// Initializes a new session instance. - /// - /// The name of the session - /// The template to use - public SessionInstance(string name, SessionTemplate template) - { - Name = name; - Template = template; - SymbolTable = new SymbolTable(); - Variables = new Dictionary(); - - // Initialize symbols from template - foreach (var member in template.Members) - { - if (member.Declaration is VarDeclNode varDecl) - { - var symbol = new Symbol(varDecl.Identifier, varDecl.TypeName ?? "any"); - SymbolTable.Define(symbol); - } - else if (member.Declaration is FunctionDeclNode funcDecl) - { - var symbol = new Symbol(funcDecl.Name, "function"); - SymbolTable.Define(symbol); - } - } - } - - /// - /// Sets a variable value in the session. - /// - /// The variable name - /// The value to set - public void SetVariable(string name, object value) - { - Variables[name] = value; - } - - /// - /// Gets a variable value from the session. - /// - /// The variable name - /// The variable value or null if not found - public object? GetVariable(string name) - { - return Variables.TryGetValue(name, out var value) ? value : null; - } - - /// - /// Checks if a variable exists in the session. - /// - /// The variable name - /// True if the variable exists, false otherwise - public bool HasVariable(string name) - { - return Variables.ContainsKey(name); - } - - /// - /// Gets all variable names in the session. - /// - /// Array of variable names - public string[] GetVariableNames() - { - return Variables.Keys.ToArray(); - } - - /// - /// Clears all variables in the session. - /// - public void ClearVariables() - { - Variables.Clear(); - } - } - - /// - /// Result of session validation. - /// - public class ValidationResult - { - private readonly List _errors = new(); - - /// - /// Gets whether the validation was successful. - /// - public bool IsValid => _errors.Count == 0; - - /// - /// Gets the validation errors. - /// - public string[] Errors => _errors.ToArray(); - - /// - /// Adds an error to the validation result. - /// - /// The error message - public void AddError(string error) - { - _errors.Add(error); - } - - /// - /// Gets a formatted error message. - /// - /// The formatted error message - public string GetErrorMessage() - { - return string.Join(Environment.NewLine, _errors); - } - } -} diff --git a/HypnoScript.Compiler/Session/TranceifyFactory.cs b/HypnoScript.Compiler/Session/TranceifyFactory.cs deleted file mode 100644 index 0e107aa..0000000 --- a/HypnoScript.Compiler/Session/TranceifyFactory.cs +++ /dev/null @@ -1,398 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using HypnoScript.LexerParser.AST; -using HypnoScript.Core.Symbols; -using HypnoScript.Core.Types; - -namespace HypnoScript.Compiler.Session -{ - /// - /// Factory for creating and managing Tranceify instances. - /// - public static class TranceifyFactory - { - private static readonly Dictionary _tranceifyTemplates = new(); - private static readonly Dictionary _activeTranceifies = new(); - - /// - /// Registers a tranceify template for later instantiation. - /// - /// The name of the tranceify template - /// The tranceify template - public static void RegisterTranceifyTemplate(string name, TranceifyTemplate template) - { - _tranceifyTemplates[name] = template; - } - - /// - /// Creates a new tranceify instance from a template. - /// - /// The name of the template to use - /// The name for the new tranceify instance - /// The created tranceify instance - public static TranceifyInstance CreateTranceify(string templateName, string tranceifyName) - { - if (!_tranceifyTemplates.TryGetValue(templateName, out var template)) - { - throw new ArgumentException($"Tranceify template '{templateName}' not found."); - } - - var tranceify = new TranceifyInstance(tranceifyName, template); - _activeTranceifies[tranceifyName] = tranceify; - return tranceify; - } - - /// - /// Creates a tranceify instance directly from a TranceifyDeclNode. - /// - /// The tranceify declaration node - /// The created tranceify instance - public static TranceifyInstance CreateTranceifyFromDeclaration(TranceifyDeclNode tranceifyDecl) - { - var template = new TranceifyTemplate(tranceifyDecl.Name, tranceifyDecl.Members); - var tranceify = new TranceifyInstance(tranceifyDecl.Name, template); - _activeTranceifies[tranceifyDecl.Name] = tranceify; - return tranceify; - } - - /// - /// Gets an active tranceify by name. - /// - /// The name of the tranceify - /// The tranceify instance or null if not found - public static TranceifyInstance? GetTranceify(string tranceifyName) - { - return _activeTranceifies.TryGetValue(tranceifyName, out var tranceify) ? tranceify : null; - } - - /// - /// Removes a tranceify instance. - /// - /// The name of the tranceify to remove - /// True if the tranceify was removed, false if not found - public static bool RemoveTranceify(string tranceifyName) - { - return _activeTranceifies.Remove(tranceifyName); - } - - /// - /// Gets all active tranceify names. - /// - /// Array of active tranceify names - public static string[] GetActiveTranceifyNames() - { - return _activeTranceifies.Keys.ToArray(); - } - - /// - /// Gets all registered template names. - /// - /// Array of registered template names - public static string[] GetRegisteredTemplateNames() - { - return _tranceifyTemplates.Keys.ToArray(); - } - - /// - /// Clears all active tranceifies. - /// - public static void ClearAllTranceifies() - { - _activeTranceifies.Clear(); - } - - /// - /// Validates a tranceify declaration for type consistency. - /// - /// The tranceify declaration to validate - /// Validation result with any errors - public static ValidationResult ValidateTranceifyDeclaration(TranceifyDeclNode tranceifyDecl) - { - var result = new ValidationResult(); - var symbolTable = new SymbolTable(); - - foreach (var variable in tranceifyDecl.Members) - { - try - { - // Validate variable type - if (!string.IsNullOrEmpty(variable.TypeName)) - { - // Note: HypnoType.FromString doesn't exist, so we'll skip type validation for now - // var type = HypnoType.FromString(variable.TypeName); - // if (type == null) - // { - // result.AddError($"Unknown type '{variable.TypeName}' for variable '{variable.Identifier}'"); - // } - } - - // Check for duplicate variable names - if (symbolTable.HasSymbol(variable.Identifier)) - { - result.AddError($"Duplicate variable name '{variable.Identifier}' in tranceify '{tranceifyDecl.Name}'"); - } - else - { - var symbol = new Symbol(variable.Identifier, variable.TypeName ?? "any"); - symbolTable.Define(symbol); - } - } - catch (Exception ex) - { - result.AddError($"Error validating tranceify variable: {ex.Message}"); - } - } - - return result; - } - - /// - /// Links a tranceify to a session for variable sharing. - /// - /// The name of the tranceify - /// The name of the session to link to - /// True if the link was successful, false otherwise - public static bool LinkToSession(string tranceifyName, string sessionName) - { - if (!_activeTranceifies.TryGetValue(tranceifyName, out var tranceify)) - { - return false; - } - - var session = SessionFactory.GetSession(sessionName); - if (session == null) - { - return false; - } - - tranceify.LinkSession(session); - return true; - } - - /// - /// Unlinks a tranceify from its session. - /// - /// The name of the tranceify - /// True if the unlink was successful, false otherwise - public static bool UnlinkFromSession(string tranceifyName) - { - if (!_activeTranceifies.TryGetValue(tranceifyName, out var tranceify)) - { - return false; - } - - tranceify.UnlinkSession(); - return true; - } - } - - /// - /// Template for creating tranceify instances. - /// - public class TranceifyTemplate - { - /// - /// The name of the tranceify template. - /// - public string Name { get; } - - /// - /// The variables of the tranceify. - /// - public List Variables { get; } - - /// - /// Initializes a new tranceify template. - /// - /// The name of the template - /// The tranceify variables - public TranceifyTemplate(string name, List variables) - { - Name = name; - Variables = variables ?? new List(); - } - } - - /// - /// Represents a tranceify instance. - /// - public class TranceifyInstance - { - /// - /// The name of the tranceify instance. - /// - public string Name { get; } - - /// - /// The template used to create this tranceify. - /// - public TranceifyTemplate Template { get; } - - /// - /// The symbol table for this tranceify. - /// - public SymbolTable SymbolTable { get; } - - /// - /// The variables in this tranceify. - /// - public Dictionary Variables { get; } - - /// - /// The linked session instance. - /// - public SessionInstance? LinkedSession { get; private set; } - - /// - /// Initializes a new tranceify instance. - /// - /// The name of the tranceify - /// The template to use - public TranceifyInstance(string name, TranceifyTemplate template) - { - Name = name; - Template = template; - SymbolTable = new SymbolTable(); - Variables = new Dictionary(); - - // Initialize symbols from template - foreach (var variable in template.Variables) - { - var symbol = new Symbol(variable.Identifier, variable.TypeName ?? "any"); - SymbolTable.Define(symbol); - } - } - - /// - /// Sets a variable value in the tranceify. - /// - /// The variable name - /// The value to set - public void SetVariable(string name, object value) - { - Variables[name] = value; - - // If linked to a session, also set the variable there - if (LinkedSession != null && LinkedSession.SymbolTable.HasSymbol(name)) - { - LinkedSession.SetVariable(name, value); - } - } - - /// - /// Gets a variable value from the tranceify. - /// - /// The variable name - /// The variable value or null if not found - public object? GetVariable(string name) - { - // First check tranceify variables - if (Variables.TryGetValue(name, out var value)) - { - return value; - } - - // Then check linked session variables - if (LinkedSession != null) - { - return LinkedSession.GetVariable(name); - } - - return null; - } - - /// - /// Checks if a variable exists in the tranceify or linked session. - /// - /// The variable name - /// True if the variable exists, false otherwise - public bool HasVariable(string name) - { - if (Variables.ContainsKey(name)) - { - return true; - } - - return LinkedSession?.HasVariable(name) ?? false; - } - - /// - /// Gets all variable names in the tranceify and linked session. - /// - /// Array of variable names - public string[] GetVariableNames() - { - var names = new HashSet(Variables.Keys); - - if (LinkedSession != null) - { - foreach (var name in LinkedSession.GetVariableNames()) - { - names.Add(name); - } - } - - return names.ToArray(); - } - - /// - /// Links this tranceify to a session. - /// - /// The session to link to - public void LinkSession(SessionInstance session) - { - LinkedSession = session; - } - - /// - /// Unlinks this tranceify from its session. - /// - public void UnlinkSession() - { - LinkedSession = null; - } - - /// - /// Clears all variables in the tranceify. - /// - public void ClearVariables() - { - Variables.Clear(); - } - - /// - /// Gets the tranceify state as a dictionary. - /// - /// Dictionary containing all variable values - public Dictionary GetState() - { - var state = new Dictionary(Variables); - - if (LinkedSession != null) - { - foreach (var kvp in LinkedSession.Variables) - { - if (!state.ContainsKey(kvp.Key)) - { - state[kvp.Key] = kvp.Value; - } - } - } - - return state; - } - - /// - /// Sets the tranceify state from a dictionary. - /// - /// Dictionary containing variable values - public void SetState(Dictionary state) - { - foreach (var kvp in state) - { - SetVariable(kvp.Key, kvp.Value); - } - } - } -} diff --git a/HypnoScript.Core/Configuration/AppConfiguration.cs b/HypnoScript.Core/Configuration/AppConfiguration.cs deleted file mode 100644 index e81367c..0000000 --- a/HypnoScript.Core/Configuration/AppConfiguration.cs +++ /dev/null @@ -1,343 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Text.Json; - -namespace HypnoScript.Core.Configuration -{ - /// - /// Central configuration management for HypnoScript CLI and Runtime. - /// - public class AppConfiguration - { - private static AppConfiguration? _instance; - private static readonly object _lock = new object(); - - /// - /// Gets the singleton instance of AppConfiguration. - /// - public static AppConfiguration Instance - { - get - { - if (_instance == null) - { - lock (_lock) - { - _instance ??= new AppConfiguration(); - } - } - return _instance; - } - } - - /// - /// CLI-specific configuration settings. - /// - public CliSettings Cli { get; set; } = new(); - - /// - /// Runtime-specific configuration settings. - /// - public RuntimeSettings Runtime { get; set; } = new(); - - /// - /// Logging configuration settings. - /// - public LoggingSettings Logging { get; set; } = new(); - - /// - /// Development and debugging settings. - /// - public DevelopmentSettings Development { get; set; } = new(); - - private AppConfiguration() - { - LoadConfiguration(); - } - - /// - /// Loads configuration from file or creates default configuration. - /// - public void LoadConfiguration() - { - var configPath = GetConfigFilePath(); - - if (File.Exists(configPath)) - { - try - { - var json = File.ReadAllText(configPath); - var config = JsonSerializer.Deserialize(json); - if (config != null) - { - Cli = config.Cli; - Runtime = config.Runtime; - Logging = config.Logging; - Development = config.Development; - } - } - catch (Exception ex) - { - Console.WriteLine($"[WARN] Failed to load configuration: {ex.Message}"); - Console.WriteLine("[INFO] Using default configuration."); - } - } - else - { - SaveConfiguration(); // Save default configuration - } - } - - /// - /// Saves the current configuration to file. - /// - public void SaveConfiguration() - { - try - { - var configPath = GetConfigFilePath(); - var configDir = Path.GetDirectoryName(configPath); - - if (!string.IsNullOrEmpty(configDir) && !Directory.Exists(configDir)) - { - Directory.CreateDirectory(configDir); - } - - var options = new JsonSerializerOptions { WriteIndented = true }; - var json = JsonSerializer.Serialize(this, options); - File.WriteAllText(configPath, json); - } - catch (Exception ex) - { - Console.WriteLine($"[ERROR] Failed to save configuration: {ex.Message}"); - } - } - - /// - /// Gets the configuration file path. - /// - /// The path to the configuration file - private static string GetConfigFilePath() - { - var appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); - return Path.Combine(appData, "HypnoScript", "config.json"); - } - - /// - /// Resets configuration to default values. - /// - public void ResetToDefaults() - { - Cli = new CliSettings(); - Runtime = new RuntimeSettings(); - Logging = new LoggingSettings(); - Development = new DevelopmentSettings(); - SaveConfiguration(); - } - } - - /// - /// CLI-specific configuration settings. - /// - public class CliSettings - { - /// - /// Default timeout for CLI operations in milliseconds. - /// - public int DefaultTimeout { get; set; } = 30000; - - /// - /// Maximum number of concurrent operations. - /// - public int MaxConcurrentOperations { get; set; } = 4; - - /// - /// Whether to show verbose output by default. - /// - public bool VerboseOutput { get; set; } = false; - - /// - /// Whether to enable colored output. - /// - public bool ColoredOutput { get; set; } = true; - - /// - /// Default output format for commands. - /// - public string DefaultOutputFormat { get; set; } = "text"; - - /// - /// Whether to enable auto-completion. - /// - public bool EnableAutoCompletion { get; set; } = true; - - /// - /// History file path for command history. - /// - public string HistoryFilePath { get; set; } = "~/.hypnoscript_history"; - - /// - /// Maximum number of history entries to keep. - /// - public int MaxHistoryEntries { get; set; } = 1000; - } - - /// - /// Runtime-specific configuration settings. - /// - public class RuntimeSettings - { - /// - /// Maximum execution time for scripts in milliseconds. - /// - public int MaxExecutionTime { get; set; } = 300000; // 5 minutes - - /// - /// Maximum memory usage in MB. - /// - public int MaxMemoryUsage { get; set; } = 512; - - /// - /// Whether to enable garbage collection during execution. - /// - public bool EnableGarbageCollection { get; set; } = true; - - /// - /// Garbage collection frequency in milliseconds. - /// - public int GarbageCollectionInterval { get; set; } = 10000; - - /// - /// Whether to enable stack trace collection. - /// - public bool EnableStackTrace { get; set; } = true; - - /// - /// Maximum stack depth for function calls. - /// - public int MaxStackDepth { get; set; } = 1000; - - /// - /// Whether to enable built-in function caching. - /// - public bool EnableBuiltinCaching { get; set; } = true; - - /// - /// Cache size for built-in functions. - /// - public int BuiltinCacheSize { get; set; } = 1000; - - /// - /// Whether to enable type checking during execution. - /// - public bool EnableTypeChecking { get; set; } = true; - - /// - /// Whether to enable strict mode. - /// - public bool StrictMode { get; set; } = false; - } - - /// - /// Logging configuration settings. - /// - public class LoggingSettings - { - /// - /// Minimum log level to output. - /// - public string LogLevel { get; set; } = "INFO"; - - /// - /// Whether to enable file logging. - /// - public bool EnableFileLogging { get; set; } = true; - - /// - /// Log file path. - /// - public string LogFilePath { get; set; } = "logs/hypnoscript.log"; - - /// - /// Maximum log file size in MB. - /// - public int MaxLogFileSize { get; set; } = 10; - - /// - /// Number of log files to keep. - /// - public int MaxLogFiles { get; set; } = 5; - - /// - /// Whether to enable console logging. - /// - public bool EnableConsoleLogging { get; set; } = true; - - /// - /// Whether to include timestamps in log messages. - /// - public bool IncludeTimestamps { get; set; } = true; - - /// - /// Whether to include thread information in log messages. - /// - public bool IncludeThreadInfo { get; set; } = false; - - /// - /// Log message format. - /// - public string LogFormat { get; set; } = "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level}] {Message}"; - } - - /// - /// Development and debugging configuration settings. - /// - public class DevelopmentSettings - { - /// - /// Whether to enable debug mode. - /// - public bool DebugMode { get; set; } = false; - - /// - /// Whether to enable performance profiling. - /// - public bool EnableProfiling { get; set; } = false; - - /// - /// Whether to enable detailed error reporting. - /// - public bool DetailedErrorReporting { get; set; } = true; - - /// - /// Whether to enable source map generation. - /// - public bool EnableSourceMaps { get; set; } = false; - - /// - /// Whether to enable hot reloading. - /// - public bool EnableHotReload { get; set; } = false; - - /// - /// Whether to enable experimental features. - /// - public bool EnableExperimentalFeatures { get; set; } = false; - - /// - /// Development server port. - /// - public int DevelopmentServerPort { get; set; } = 8080; - - /// - /// Whether to enable remote debugging. - /// - public bool EnableRemoteDebugging { get; set; } = false; - - /// - /// Remote debugging port. - /// - public int RemoteDebuggingPort { get; set; } = 9222; - } -} diff --git a/HypnoScript.Core/HypnoScript.Core.csproj b/HypnoScript.Core/HypnoScript.Core.csproj deleted file mode 100644 index fa71b7a..0000000 --- a/HypnoScript.Core/HypnoScript.Core.csproj +++ /dev/null @@ -1,9 +0,0 @@ - - - - net8.0 - enable - enable - - - diff --git a/HypnoScript.Core/Symbols/Symbol.cs b/HypnoScript.Core/Symbols/Symbol.cs deleted file mode 100644 index ce9553c..0000000 --- a/HypnoScript.Core/Symbols/Symbol.cs +++ /dev/null @@ -1,93 +0,0 @@ -using HypnoScript.Core.Types; - -namespace HypnoScript.Core.Symbols -{ - public enum SymbolKind - { - Variable, - Function, - Session, - Record, - Parameter, - Label, - Builtin, - Module - } - - public class Symbol - { - public string Name { get; } - public string? TypeName { get; } - public object? Value { get; set; } // Falls wir Interpretieren - public SymbolKind Kind { get; } - public HypnoType? Type { get; set; } - public bool IsConstant { get; set; } - public bool IsExported { get; set; } - public string? Documentation { get; set; } - public int LineNumber { get; set; } - public int ColumnNumber { get; set; } - - public Symbol(string name, string? typeName = null, object? value = null, SymbolKind kind = SymbolKind.Variable) - { - Name = name; - TypeName = typeName; - Value = value; - Kind = kind; - } - - // Erweiterte Konstruktoren - public Symbol(string name, HypnoType type, SymbolKind kind = SymbolKind.Variable) : this(name, null, null, kind) - { - Type = type; - } - - public Symbol(string name, string typeName, SymbolKind kind, string? documentation = null) : this(name, typeName, null, kind) - { - Documentation = documentation; - } - - // Factory-Methoden - public static Symbol CreateVariable(string name, string typeName, object? value = null) - => new Symbol(name, typeName, value, SymbolKind.Variable); - - public static Symbol CreateFunction(string name, string returnType, string? documentation = null) - => new Symbol(name, returnType, null, SymbolKind.Function) { Documentation = documentation }; - - public static Symbol CreateSession(string name, string? documentation = null) - => new Symbol(name, "session", null, SymbolKind.Session) { Documentation = documentation }; - - public static Symbol CreateRecord(string name, string? documentation = null) - => new Symbol(name, "record", null, SymbolKind.Record) { Documentation = documentation }; - - public static Symbol CreateBuiltin(string name, string returnType, string? documentation = null) - => new Symbol(name, returnType, null, SymbolKind.Builtin) { Documentation = documentation }; - - public static Symbol CreateLabel(string name) - => new Symbol(name, null, null, SymbolKind.Label); - - // Hilfsmethoden - public bool IsFunction => Kind == SymbolKind.Function || Kind == SymbolKind.Builtin; - public bool IsType => Kind == SymbolKind.Session || Kind == SymbolKind.Record; - public bool IsVariable => Kind == SymbolKind.Variable || Kind == SymbolKind.Parameter; - - public override string ToString() - { - var typeInfo = Type?.ToString() ?? TypeName ?? "unknown"; - var kindInfo = Kind.ToString().ToLower(); - return $"{kindInfo} {Name}: {typeInfo}"; - } - - public string GetFullDescription() - { - var result = $"{Kind} '{Name}'"; - if (Type != null) result += $" of type {Type}"; - else if (TypeName != null) result += $" of type {TypeName}"; - - if (IsConstant) result += " (constant)"; - if (IsExported) result += " (exported)"; - if (Documentation != null) result += $" - {Documentation}"; - - return result; - } - } -} diff --git a/HypnoScript.Core/Symbols/SymbolTable.cs b/HypnoScript.Core/Symbols/SymbolTable.cs deleted file mode 100644 index 99f9344..0000000 --- a/HypnoScript.Core/Symbols/SymbolTable.cs +++ /dev/null @@ -1,222 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace HypnoScript.Core.Symbols -{ - // Runtime-Level: Erweiterte SymbolTable mit Debugging und Scope-Analyse - public class SymbolTable - { - private readonly SymbolTable? _enclosing; - private readonly Dictionary _symbols = new(); - private readonly List _childScopes = new(); - public string ScopeName { get; set; } = "Global"; - public int ScopeLevel { get; } - - public SymbolTable(SymbolTable? enclosing = null, string scopeName = "Global") - { - _enclosing = enclosing; - ScopeName = scopeName; - ScopeLevel = enclosing?.ScopeLevel + 1 ?? 0; - enclosing?._childScopes.Add(this); - } - - public bool Define(Symbol sym) - { - if (_symbols.ContainsKey(sym.Name)) - { - Console.Error.WriteLine($"[SymbolTable] Symbol '{sym.Name}' is already defined in scope '{ScopeName}'."); - return false; - } - _symbols[sym.Name] = sym; - return true; - } - - public Symbol? Resolve(string name) - { - if (_symbols.TryGetValue(name, out var sym)) - return sym; - return _enclosing?.Resolve(name); - } - - public Symbol? ResolveLocal(string name) - { - _symbols.TryGetValue(name, out var sym); - return sym; - } - - public bool Assign(string name, object? value) - { - var symbol = Resolve(name); - if (symbol == null) - { - Console.Error.WriteLine($"[SymbolTable] Cannot assign to undefined symbol '{name}'."); - return false; - } - if (symbol.IsConstant) - { - Console.Error.WriteLine($"[SymbolTable] Cannot assign to constant symbol '{name}'."); - return false; - } - symbol.Value = value; - return true; - } - - // Runtime-Level: Methode, um den aktuellen Scope-Stack als String auszugeben - public string DebugScope() - { - var result = $"Scope '{ScopeName}' (Level {ScopeLevel}):\n"; - foreach (var kvp in _symbols.OrderBy(x => x.Key)) - { - var symbol = kvp.Value; - var valueInfo = symbol.Value != null ? $" = {symbol.Value}" : ""; - var constInfo = symbol.IsConstant ? " (const)" : ""; - var exportInfo = symbol.IsExported ? " (exported)" : ""; - result += $" {symbol.Kind} {kvp.Key}: {symbol.TypeName}{valueInfo}{constInfo}{exportInfo}\n"; - } - if (_enclosing != null) - { - result += "\nEnclosing Scope:\n" + _enclosing.DebugScope(); - } - return result; - } - - // Neue Runtime-Features - public IEnumerable GetAllSymbols() - { - return _symbols.Values.OrderBy(s => s.Name); - } - - public IEnumerable GetSymbolsByKind(SymbolKind kind) - { - return _symbols.Values.Where(s => s.Kind == kind).OrderBy(s => s.Name); - } - - public IEnumerable GetExportedSymbols() - { - return _symbols.Values.Where(s => s.IsExported).OrderBy(s => s.Name); - } - - public IEnumerable GetConstants() - { - return _symbols.Values.Where(s => s.IsConstant).OrderBy(s => s.Name); - } - - public int SymbolCount => _symbols.Count; - - public bool HasSymbol(string name) - { - return _symbols.ContainsKey(name); - } - - public bool RemoveSymbol(string name) - { - return _symbols.Remove(name); - } - - public void Clear() - { - _symbols.Clear(); - } - - // Scope-Hierarchie-Management - public SymbolTable? GetEnclosingScope() => _enclosing; - public IEnumerable GetChildScopes() => _childScopes; - - public SymbolTable GetRootScope() - { - var current = this; - while (current._enclosing != null) - { - current = current._enclosing; - } - return current; - } - - public int GetScopeDepth() - { - var depth = 0; - var current = this; - while (current._enclosing != null) - { - depth++; - current = current._enclosing; - } - return depth; - } - - // Symbol-Statistiken - public Dictionary GetSymbolStatistics() - { - return _symbols.Values - .GroupBy(s => s.Kind) - .ToDictionary(g => g.Key, g => g.Count()); - } - - public string GetScopeSummary() - { - var stats = GetSymbolStatistics(); - var summary = $"Scope '{ScopeName}' (Level {ScopeLevel}): {SymbolCount} symbols\n"; - foreach (var stat in stats.OrderBy(s => s.Key)) - { - summary += $" {stat.Key}: {stat.Value}\n"; - } - return summary; - } - - // Symbol-Suche mit Filter - public IEnumerable SearchSymbols(string pattern, SymbolKind? kind = null) - { - var query = _symbols.Values.AsEnumerable(); - - if (kind.HasValue) - query = query.Where(s => s.Kind == kind.Value); - - return query.Where(s => s.Name.Contains(pattern, StringComparison.OrdinalIgnoreCase)) - .OrderBy(s => s.Name); - } - - // Symbol-Validierung - public List ValidateSymbols() - { - var errors = new List(); - - foreach (var symbol in _symbols.Values) - { - if (string.IsNullOrWhiteSpace(symbol.Name)) - errors.Add($"Symbol has empty name in scope '{ScopeName}'"); - - if (symbol.Kind == SymbolKind.Function && string.IsNullOrEmpty(symbol.TypeName)) - errors.Add($"Function '{symbol.Name}' has no return type"); - - if (symbol.IsConstant && symbol.Value == null) - errors.Add($"Constant '{symbol.Name}' has no initial value"); - } - - return errors; - } - - // Scope-Merging (für Module/Imports) - public void MergeFrom(SymbolTable other, bool overwrite = false) - { - foreach (var kvp in other._symbols) - { - if (overwrite || !_symbols.ContainsKey(kvp.Key)) - { - _symbols[kvp.Key] = kvp.Value; - } - } - } - - // Scope-Export (für Module) - public SymbolTable ExportScope() - { - var exported = new SymbolTable(null, $"{ScopeName}_Exported"); - foreach (var symbol in _symbols.Values.Where(s => s.IsExported)) - { - exported.Define(symbol); - } - return exported; - } - } -} diff --git a/HypnoScript.Core/Types/HypnoType.cs b/HypnoScript.Core/Types/HypnoType.cs deleted file mode 100644 index bfe603d..0000000 --- a/HypnoScript.Core/Types/HypnoType.cs +++ /dev/null @@ -1,126 +0,0 @@ -namespace HypnoScript.Core.Types -{ - public enum HypnoBaseType - { - Number, - String, - Boolean, - Trance, // Neuer Basistyp - Array, // Array-Typ - Object, // Objekt-Typ - Function, // Funktions-Typ - Session, // Session-Typ - Record, // Record/Struct-Typ - Unknown, - // ... - } - - public class HypnoType - { - public HypnoBaseType BaseType { get; } - public string? Name { get; } - public HypnoType? ElementType { get; } // Für Arrays - public Dictionary? Fields { get; } // Für Records/Objects - public List? ParameterTypes { get; } // Für Functions - public HypnoType? ReturnType { get; } // Für Functions - - public HypnoType(HypnoBaseType baseType, string? name = null) - { - BaseType = baseType; - Name = name; - } - - // Konstruktor für Array-Typen - public HypnoType(HypnoType elementType) : this(HypnoBaseType.Array) - { - ElementType = elementType; - } - - // Konstruktor für Record-Typen - public HypnoType(string name, Dictionary fields) : this(HypnoBaseType.Record, name) - { - Fields = fields; - } - - // Konstruktor für Funktions-Typen - public HypnoType(List parameterTypes, HypnoType returnType) : this(HypnoBaseType.Function) - { - ParameterTypes = parameterTypes; - ReturnType = returnType; - } - - public static readonly HypnoType Number = new HypnoType(HypnoBaseType.Number); - public static readonly HypnoType String = new HypnoType(HypnoBaseType.String); - public static readonly HypnoType Boolean = new HypnoType(HypnoBaseType.Boolean); - public static readonly HypnoType Unknown = new HypnoType(HypnoBaseType.Unknown); - - // Factory-Methoden für komplexe Typen - public static HypnoType CreateArray(HypnoType elementType) => new HypnoType(elementType); - public static HypnoType CreateRecord(string name, Dictionary fields) => new HypnoType(name, fields); - public static HypnoType CreateFunction(List parameterTypes, HypnoType returnType) => new HypnoType(parameterTypes, returnType); - - // Typprüfungs-Methoden - public bool IsArray => BaseType == HypnoBaseType.Array; - public bool IsRecord => BaseType == HypnoBaseType.Record; - public bool IsFunction => BaseType == HypnoBaseType.Function; - public bool IsPrimitive => BaseType == HypnoBaseType.Number || BaseType == HypnoBaseType.String || BaseType == HypnoBaseType.Boolean; - - // Kompatibilitätsprüfung - public bool IsCompatibleWith(HypnoType other) - { - if (BaseType != other.BaseType) return false; - - switch (BaseType) - { - case HypnoBaseType.Array: - return ElementType?.IsCompatibleWith(other.ElementType!) ?? false; - case HypnoBaseType.Record: - if (Fields == null || other.Fields == null) return false; - if (Fields.Count != other.Fields.Count) return false; - foreach (var field in Fields) - { - if (!other.Fields.ContainsKey(field.Key)) return false; - if (!field.Value.IsCompatibleWith(other.Fields[field.Key])) return false; - } - return true; - case HypnoBaseType.Function: - if (ParameterTypes?.Count != other.ParameterTypes?.Count) return false; - if (!ReturnType?.IsCompatibleWith(other.ReturnType!) ?? false) return false; - for (int i = 0; i < ParameterTypes?.Count; i++) - { - if (!ParameterTypes![i].IsCompatibleWith(other.ParameterTypes![i])) return false; - } - return true; - default: - return true; - } - } - - public override string ToString() - { - return BaseType switch - { - HypnoBaseType.Array => $"[{ElementType}]", - HypnoBaseType.Record => $"Record<{Name}>", - HypnoBaseType.Function => $"Function<{string.Join(",", ParameterTypes ?? new List())} -> {ReturnType}>", - _ => Name ?? BaseType.ToString() - }; - } - - public override bool Equals(object? obj) - { - if (obj is not HypnoType other) return false; - return BaseType == other.BaseType && - Name == other.Name && - (ElementType?.Equals(other.ElementType) ?? other.ElementType == null) && - (Fields?.Count == other.Fields?.Count) && - (ParameterTypes?.Count == other.ParameterTypes?.Count) && - (ReturnType?.Equals(other.ReturnType) ?? other.ReturnType == null); - } - - public override int GetHashCode() - { - return HashCode.Combine(BaseType, Name, ElementType, Fields, ParameterTypes, ReturnType); - } - } -} diff --git a/HypnoScript.Dokumentation/blog/2019-05-28-first-blog-post.md b/HypnoScript.Dokumentation/blog/2019-05-28-first-blog-post.md deleted file mode 100644 index d3032ef..0000000 --- a/HypnoScript.Dokumentation/blog/2019-05-28-first-blog-post.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -slug: first-blog-post -title: First Blog Post -authors: [slorber, yangshun] -tags: [hola, docusaurus] ---- - -Lorem ipsum dolor sit amet... - - - -...consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet diff --git a/HypnoScript.Dokumentation/blog/2019-05-29-long-blog-post.md b/HypnoScript.Dokumentation/blog/2019-05-29-long-blog-post.md deleted file mode 100644 index eb4435d..0000000 --- a/HypnoScript.Dokumentation/blog/2019-05-29-long-blog-post.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -slug: long-blog-post -title: Long Blog Post -authors: yangshun -tags: [hello, docusaurus] ---- - -This is the summary of a very long blog post, - -Use a `` comment to limit blog post size in the list view. - - - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet diff --git a/HypnoScript.Dokumentation/blog/2021-08-01-mdx-blog-post.mdx b/HypnoScript.Dokumentation/blog/2021-08-01-mdx-blog-post.mdx deleted file mode 100644 index 0c4b4a4..0000000 --- a/HypnoScript.Dokumentation/blog/2021-08-01-mdx-blog-post.mdx +++ /dev/null @@ -1,24 +0,0 @@ ---- -slug: mdx-blog-post -title: MDX Blog Post -authors: [slorber] -tags: [docusaurus] ---- - -Blog posts support [Docusaurus Markdown features](https://docusaurus.io/docs/markdown-features), such as [MDX](https://mdxjs.com/). - -:::tip - -Use the power of React to create interactive blog posts. - -::: - -{/* truncate */} - -For example, use JSX to create an interactive button: - -```js - -``` - - diff --git a/HypnoScript.Dokumentation/blog/2021-08-26-welcome/docusaurus-plushie-banner.jpeg b/HypnoScript.Dokumentation/blog/2021-08-26-welcome/docusaurus-plushie-banner.jpeg deleted file mode 100644 index 11bda09..0000000 Binary files a/HypnoScript.Dokumentation/blog/2021-08-26-welcome/docusaurus-plushie-banner.jpeg and /dev/null differ diff --git a/HypnoScript.Dokumentation/blog/2021-08-26-welcome/index.md b/HypnoScript.Dokumentation/blog/2021-08-26-welcome/index.md deleted file mode 100644 index 349ea07..0000000 --- a/HypnoScript.Dokumentation/blog/2021-08-26-welcome/index.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -slug: welcome -title: Welcome -authors: [slorber, yangshun] -tags: [facebook, hello, docusaurus] ---- - -[Docusaurus blogging features](https://docusaurus.io/docs/blog) are powered by the [blog plugin](https://docusaurus.io/docs/api/plugins/@docusaurus/plugin-content-blog). - -Here are a few tips you might find useful. - - - -Simply add Markdown files (or folders) to the `blog` directory. - -Regular blog authors can be added to `authors.yml`. - -The blog post date can be extracted from filenames, such as: - -- `2019-05-30-welcome.md` -- `2019-05-30-welcome/index.md` - -A blog post folder can be convenient to co-locate blog post images: - -![Docusaurus Plushie](./docusaurus-plushie-banner.jpeg) - -The blog supports tags as well! - -**And if you don't want a blog**: just delete this directory, and use `blog: false` in your Docusaurus config. diff --git a/HypnoScript.Dokumentation/blog/authors.yml b/HypnoScript.Dokumentation/blog/authors.yml deleted file mode 100644 index 0fd3987..0000000 --- a/HypnoScript.Dokumentation/blog/authors.yml +++ /dev/null @@ -1,25 +0,0 @@ -yangshun: - name: Yangshun Tay - title: Ex-Meta Staff Engineer, Co-founder GreatFrontEnd - url: https://linkedin.com/in/yangshun - image_url: https://github.com/yangshun.png - page: true - socials: - x: yangshunz - linkedin: yangshun - github: yangshun - newsletter: https://www.greatfrontend.com - -slorber: - name: Sébastien Lorber - title: Docusaurus maintainer - url: https://sebastienlorber.com - image_url: https://github.com/slorber.png - page: - # customize the url of the author page at /blog/authors/ - permalink: '/all-sebastien-lorber-articles' - socials: - x: sebastienlorber - linkedin: sebastienlorber - github: slorber - newsletter: https://thisweekinreact.com diff --git a/HypnoScript.Dokumentation/blog/tags.yml b/HypnoScript.Dokumentation/blog/tags.yml deleted file mode 100644 index bfaa778..0000000 --- a/HypnoScript.Dokumentation/blog/tags.yml +++ /dev/null @@ -1,19 +0,0 @@ -facebook: - label: Facebook - permalink: /facebook - description: Facebook tag description - -hello: - label: Hello - permalink: /hello - description: Hello tag description - -docusaurus: - label: Docusaurus - permalink: /docusaurus - description: Docusaurus tag description - -hola: - label: Hola - permalink: /hola - description: Hola tag description diff --git a/HypnoScript.Dokumentation/docs/builtins/overview.md b/HypnoScript.Dokumentation/docs/builtins/overview.md deleted file mode 100644 index 966a99a..0000000 --- a/HypnoScript.Dokumentation/docs/builtins/overview.md +++ /dev/null @@ -1,245 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Builtin-Funktionen Übersicht - -HypnoScript bietet eine umfassende Standardbibliothek mit über **200+ eingebauten Funktionen**, die in verschiedene Kategorien unterteilt sind. Diese Funktionen sind direkt in der Sprache verfügbar und erfordern keine zusätzlichen Imports. - -## Kategorien - -### 🔢 Array-Funktionen - -Funktionen für die Arbeit mit Arrays und Listen. - -| Funktion | Beschreibung | Beispiel | -| ----------------------------- | --------------------- | --------------------------------- | -| `ArrayLength(arr)` | Länge des Arrays | `ArrayLength([1,2,3])` → `3` | -| `ArrayGet(arr, index)` | Element an Index | `ArrayGet([1,2,3], 1)` → `2` | -| `ArraySet(arr, index, value)` | Setzt Wert an Index | `ArraySet(arr, 0, "neu")` | -| `ArraySort(arr)` | Sortiert Array | `ArraySort([3,1,2])` → `[1,2,3]` | -| `ShuffleArray(arr)` | Mischt Array zufällig | `ShuffleArray([1,2,3,4,5])` | -| `SumArray(arr)` | Summe aller Werte | `SumArray([1,2,3,4,5])` → `15` | -| `AverageArray(arr)` | Durchschnitt | `AverageArray([1,2,3,4,5])` → `3` | - -[→ Detaillierte Array-Funktionen](./array-functions) - -### 📝 String-Funktionen - -Funktionen für String-Manipulation und -Analyse. - -| Funktion | Beschreibung | Beispiel | -| ------------------------------- | --------------- | ------------------------------------ | -| `Length(str)` | String-Länge | `Length("Hallo")` → `5` | -| `Substring(str, start, length)` | Teilstring | `Substring("Hallo", 1, 3)` → `"all"` | -| `ToUpper(str)` | Großbuchstaben | `ToUpper("hallo")` → `"HALLO"` | -| `Reverse(str)` | Kehrt String um | `Reverse("Hallo")` → `"ollaH"` | -| `IsPalindrome(str)` | Prüft Palindrom | `IsPalindrome("anna")` → `true` | -| `CountWords(str)` | Zählt Wörter | `CountWords("Hallo Welt")` → `2` | - -[→ Detaillierte String-Funktionen](./string-functions) - -### 🧮 Mathematische Funktionen - -Umfassende mathematische Operationen und Berechnungen. - -| Funktion | Beschreibung | Beispiel | -| ---------------------------- | --------------------------- | ----------------------- | -| `Sin(x)`, `Cos(x)`, `Tan(x)` | Trigonometrische Funktionen | `Sin(90)` → `1.0` | -| `Sqrt(x)` | Quadratwurzel | `Sqrt(16)` → `4.0` | -| `Pow(x, y)` | Potenz | `Pow(2, 3)` → `8.0` | -| `Factorial(n)` | Fakultät | `Factorial(5)` → `120` | -| `Random()` | Zufallszahl [0,1) | `Random()` → `0.123...` | -| `IsPrime(n)` | Prüft Primzahl | `IsPrime(17)` → `true` | - -[→ Detaillierte Mathematische Funktionen](./math-functions) - -### 🛠️ Utility-Funktionen - -Allgemeine Hilfsfunktionen für verschiedene Anwendungsfälle. - -| Funktion | Beschreibung | Beispiel | -| ----------------------- | -------------------- | ----------------------------------------------------------- | -| `Clamp(x, min, max)` | Begrenzt Wert | `Clamp(15, 0, 10)` → `10` | -| `IsEven(x)`, `IsOdd(x)` | Gerade/Ungerade | `IsEven(4)` → `true` | -| `IsValidEmail(str)` | E-Mail-Validierung | `IsValidEmail("test@example.com")` → `true` | -| `GenerateUUID()` | UUID generieren | `GenerateUUID()` → `"123e4567-e89b-12d3-a456-426614174000"` | -| `FormatCurrency(x)` | Währungsformatierung | `FormatCurrency(1234.56)` → `"$1,234.56"` | - -[→ Detaillierte Utility-Funktionen](./utility-functions) - -### 💻 System-Funktionen - -Funktionen für System-Interaktion und -Informationen. - -| Funktion | Beschreibung | Beispiel | -| --------------------- | --------------- | --------------------------------------- | -| `GetCurrentTime()` | Unix-Timestamp | `GetCurrentTime()` → `1640995200` | -| `GetCurrentDate()` | Aktuelles Datum | `GetCurrentDate()` → `"2024-01-01"` | -| `GetMachineName()` | Rechnername | `GetMachineName()` → `"DESKTOP-ABC123"` | -| `GetUserName()` | Benutzername | `GetUserName()` → `"john.doe"` | -| `GetProcessorCount()` | CPU-Kerne | `GetProcessorCount()` → `8` | -| `ClearScreen()` | Konsole löschen | `ClearScreen()` | - -[→ Detaillierte System-Funktionen](./system-functions) - -### 🕒 Zeit- und Datumsfunktionen - -Erweiterte Funktionen für Zeit- und Datumsverarbeitung. - -| Funktion | Beschreibung | Beispiel | -| ------------------- | --------------- | ------------------------------------------- | -| `GetDayOfWeek()` | Wochentag | `GetDayOfWeek()` → `1` (Montag) | -| `GetDayOfYear()` | Tag im Jahr | `GetDayOfYear()` → `1` | -| `IsLeapYear(y)` | Schaltjahr | `IsLeapYear(2024)` → `true` | -| `AddDays(date, n)` | Tage addieren | `AddDays("2024-01-01", 7)` → `"2024-01-08"` | -| `GetAge(birthDate)` | Alter berechnen | `GetAge("1990-01-01")` → `34` | - -[→ Detaillierte Zeit- und Datumsfunktionen](./time-date-functions) - -### 📊 Statistik-Funktionen - -Funktionen für statistische Berechnungen und Analysen. - -| Funktion | Beschreibung | Beispiel | -| --------------------------------- | ------------------ | -------------------------------------------------- | -| `CalculateMean(arr)` | Mittelwert | `CalculateMean([1,2,3,4,5])` → `3` | -| `CalculateStandardDeviation(arr)` | Standardabweichung | `CalculateStandardDeviation([1,2,3,4,5])` → `1.58` | -| `LinearRegression(x, y)` | Lineare Regression | `LinearRegression([1,2,3], [2,4,6])` → `2.0` | - -[→ Detaillierte Statistik-Funktionen](./statistics-functions) - -### 🔐 Hashing/Encoding - -Funktionen für Kryptographie und Datenkodierung. - -| Funktion | Beschreibung | Beispiel | -| ------------------- | ------------------ | ------------------------------------------------------------------------------------------- | -| `HashMD5(str)` | MD5-Hash | `HashMD5("test")` → `"098f6bcd4621d373cade4e832627b4f6"` | -| `HashSHA256(str)` | SHA256-Hash | `HashSHA256("test")` → `"9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"` | -| `Base64Encode(str)` | Base64-Kodierung | `Base64Encode("test")` → `"dGVzdA=="` | -| `Base64Decode(str)` | Base64-Dekodierung | `Base64Decode("dGVzdA==")` → `"test"` | - -[→ Detaillierte Hashing/Encoding-Funktionen](./hashing-encoding) - -### 🧠 Hypnotische Spezialfunktionen - -Einzigartige Funktionen für hypnotische Anwendungen. - -| Funktion | Beschreibung | Beispiel | -| ------------------------------ | ----------------------- | ----------------------------------------- | -| `DeepTrance(duration)` | Tiefe Trance | `DeepTrance(5000)` | -| `HypnoticCountdown(from)` | Countdown | `HypnoticCountdown(10)` | -| `TranceInduction(name)` | Trance-Induktion | `TranceInduction("Max")` | -| `HypnoticSuggestion(msg)` | Suggestion | `HypnoticSuggestion("Du bist entspannt")` | -| `ProgressiveRelaxation(steps)` | Progressive Entspannung | `ProgressiveRelaxation(5)` | - -[→ Detaillierte Hypnotische Funktionen](./hypnotic-functions) - -### 📚 Dictionary-Funktionen - -Funktionen für die Arbeit mit Key-Value-Paaren. - -| Funktion | Beschreibung | Beispiel | -| --------------------------------- | ----------------- | ------------------------------------------- | -| `CreateDictionary()` | Leeres Dictionary | `CreateDictionary()` → `{}` | -| `DictionaryKeys(dict)` | Alle Keys | `DictionaryKeys(dict)` → `["key1", "key2"]` | -| `DictionaryGet(dict, key)` | Wert abrufen | `DictionaryGet(dict, "key1")` → `"value1"` | -| `DictionarySet(dict, key, value)` | Wert setzen | `DictionarySet(dict, "key1", "value1")` | - -[→ Detaillierte Dictionary-Funktionen](./dictionary-functions) - -### 📁 Datei-Funktionen - -Funktionen für Dateisystem-Operationen. - -| Funktion | Beschreibung | Beispiel | -| -------------------------- | --------------- | ------------------------------------ | -| `FileExists(path)` | Datei existiert | `FileExists("test.txt")` → `true` | -| `ReadFile(path)` | Datei lesen | `ReadFile("test.txt")` → `"Inhalt"` | -| `WriteFile(path, content)` | Datei schreiben | `WriteFile("test.txt", "Hallo")` | -| `GetFileSize(path)` | Dateigröße | `GetFileSize("test.txt")` → `1024` | -| `FileCopy(source, dest)` | Datei kopieren | `FileCopy("source.txt", "dest.txt")` | - -[→ Detaillierte Datei-Funktionen](./file-functions) - -### 🌐 Netzwerk-Funktionen - -Funktionen für Web- und Netzwerk-Operationen. - -| Funktion | Beschreibung | Beispiel | -| --------------------- | ------------------ | ------------------------------------------------------------- | -| `HttpGet(url)` | HTTP GET-Request | `HttpGet("https://api.example.com/data")` | -| `HttpPost(url, data)` | HTTP POST-Request | `HttpPost("https://api.example.com", "data")` | -| `IsValidUrl(str)` | URL-Validierung | `IsValidUrl("https://example.com")` → `true` | -| `ExtractDomain(url)` | Domain extrahieren | `ExtractDomain("https://example.com/path")` → `"example.com"` | - -[→ Detaillierte Netzwerk-Funktionen](./network-functions) - -### ✅ Validierung-Funktionen - -Funktionen für Datenvalidierung und -formatierung. - -| Funktion | Beschreibung | Beispiel | -| ------------------------- | ------------------------- | ------------------------------------------------------ | -| `IsValidEmail(str)` | E-Mail-Validierung | `IsValidEmail("test@example.com")` → `true` | -| `IsValidPhoneNumber(str)` | Telefonnummer | `IsValidPhoneNumber("+49123456789")` → `true` | -| `IsValidCreditCard(str)` | Kreditkarte | `IsValidCreditCard("4111111111111111")` → `true` | -| `FormatPhoneNumber(str)` | Telefonnummer formatieren | `FormatPhoneNumber("1234567890")` → `"(123) 456-7890"` | - -[→ Detaillierte Validierung-Funktionen](./validation-functions) - -### ⚡ Performance-Funktionen - -Funktionen für Performance-Monitoring und Debugging. - -| Funktion | Beschreibung | Beispiel | -| --------------------- | --------------------- | ------------------------------------------------------ | -| `GetMemoryUsage()` | Speicherverbrauch | `GetMemoryUsage()` → `1048576` | -| `GetCPUUsage()` | CPU-Auslastung | `GetCPUUsage()` → `25.5` | -| `GetProcessInfo()` | Prozess-Informationen | `GetProcessInfo()` → `{id: 1234, name: "hypnoscript"}` | -| `Log(message, level)` | Logging | `Log("Debug info", "DEBUG")` | -| `Trace(message)` | Tracing | `Trace("Function called")` | - -[→ Detaillierte Performance-Funktionen](./performance-functions) - -## Verwendung - -Alle Builtin-Funktionen können direkt in HypnoScript-Code verwendet werden: - -```hyp -Focus { - entrance { - observe "Builtin-Funktionen Demo"; - } - - // Array-Funktionen - induce numbers = [1, 2, 3, 4, 5]; - induce sum = SumArray(numbers); - observe "Summe: " + sum; - - // String-Funktionen - induce text = "Hallo Welt"; - induce reversed = Reverse(text); - observe "Umgekehrt: " + reversed; - - // Mathematische Funktionen - induce sqrt = Sqrt(16); - observe "Quadratwurzel von 16: " + sqrt; - - // System-Funktionen - induce currentTime = GetCurrentTime(); - observe "Aktuelle Zeit: " + currentTime; - - // Validierung - induce isValid = IsValidEmail("test@example.com"); - observe "E-Mail gültig: " + isValid; -} Relax; -``` - -## Nächste Schritte - -- [Array-Funktionen](./array-functions) - Detaillierte Dokumentation aller Array-Funktionen -- [String-Funktionen](./string-functions) - Umfassende String-Manipulation -- [Mathematische Funktionen](./math-functions) - Mathematische Operationen und Berechnungen -- [Beispiele](../examples/basic-examples) - Praktische Beispiele für Builtin-Funktionen diff --git a/HypnoScript.Dokumentation/docs/cli/advanced-commands.md b/HypnoScript.Dokumentation/docs/cli/advanced-commands.md deleted file mode 100644 index 9f58385..0000000 --- a/HypnoScript.Dokumentation/docs/cli/advanced-commands.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Advanced CLI Commands ---- - -# Advanced CLI Commands - -This page will document advanced CLI commands. Content coming soon. diff --git a/HypnoScript.Dokumentation/docs/cli/commands.md b/HypnoScript.Dokumentation/docs/cli/commands.md deleted file mode 100644 index ccbe882..0000000 --- a/HypnoScript.Dokumentation/docs/cli/commands.md +++ /dev/null @@ -1,439 +0,0 @@ ---- -sidebar_position: 2 ---- - -# CLI-Befehle - -Die HypnoScript CLI bietet umfangreiche Befehle für Entwicklung, Testing und Deployment. - -## run - Programm ausführen - -Führt ein HypnoScript-Programm aus. - -### Syntax - -```bash -dotnet run --project HypnoScript.CLI -- run [optionen] -``` - -### Optionen - -| Option | Kurzform | Beschreibung | -| ----------- | -------- | --------------------- | -| `--verbose` | `-v` | Detaillierte Ausgabe | -| `--quiet` | `-q` | Minimale Ausgabe | -| `--output` | `-o` | Ausgabedatei | -| `--timeout` | `-t` | Timeout in Sekunden | -| `--args` | `-a` | Zusätzliche Argumente | - -### Beispiele - -```bash -# Einfaches Programm ausführen -dotnet run --project HypnoScript.CLI -- run hello.hyp - -# Mit detaillierter Ausgabe -dotnet run --project HypnoScript.CLI -- run script.hyp --verbose - -# Mit Timeout -dotnet run --project HypnoScript.CLI -- run long_script.hyp --timeout 30 - -# Ausgabe in Datei umleiten -dotnet run --project HypnoScript.CLI -- run script.hyp --output result.txt - -# Mit zusätzlichen Argumenten -dotnet run --project HypnoScript.CLI -- run script.hyp --args "param1=value1" "param2=value2" -``` - -## test - Tests ausführen - -Führt Tests für HypnoScript-Dateien aus. - -### Syntax - -```bash -dotnet run --project HypnoScript.CLI -- test [optionen] -``` - -### Optionen - -| Option | Kurzform | Beschreibung | -| ----------- | -------- | ------------------------------- | -| `--verbose` | `-v` | Detaillierte Test-Ausgabe | -| `--quiet` | `-q` | Nur Zusammenfassung | -| `--format` | `-f` | Ausgabeformat (text, json, xml) | -| `--output` | `-o` | Test-Report-Datei | -| `--filter` | `-F` | Test-Filter | - -### Beispiele - -```bash -# Alle Tests im aktuellen Verzeichnis -dotnet run --project HypnoScript.CLI -- test *.hyp - -# Spezifische Test-Datei -dotnet run --project HypnoScript.CLI -- test test_math.hyp - -# Tests mit detaillierter Ausgabe -dotnet run --project HypnoScript.CLI -- test *.hyp --verbose - -# JSON-Report generieren -dotnet run --project HypnoScript.CLI -- test *.hyp --format json --output test-report.json - -# Tests mit Filter -dotnet run --project HypnoScript.CLI -- test *.hyp --filter "math" -``` - -## build - Programm kompilieren - -Kompiliert ein HypnoScript-Programm. - -### Syntax - -```bash -dotnet run --project HypnoScript.CLI -- build [optionen] -``` - -### Optionen - -| Option | Kurzform | Beschreibung | -| ------------ | -------- | ------------------------ | -| `--output` | `-o` | Ausgabedatei | -| `--optimize` | `-O` | Optimierungen aktivieren | -| `--debug` | `-d` | Debug-Informationen | -| `--target` | `-t` | Zielformat (il, wasm) | - -### Beispiele - -```bash -# Programm kompilieren -dotnet run --project HypnoScript.CLI -- build script.hyp - -# Mit Optimierungen -dotnet run --project HypnoScript.CLI -- build script.hyp --optimize - -# Debug-Version -dotnet run --project HypnoScript.CLI -- build script.hyp --debug - -# WebAssembly-Target -dotnet run --project HypnoScript.CLI -- build script.hyp --target wasm -``` - -## debug - Debug-Modus - -Führt ein Programm im Debug-Modus aus. - -### Syntax - -```bash -dotnet run --project HypnoScript.CLI -- debug [optionen] -``` - -### Optionen - -| Option | Kurzform | Beschreibung | -| --------------- | -------- | ------------------------------ | -| `--breakpoints` | `-b` | Breakpoint-Datei | -| `--step` | `-s` | Schritt-für-Schritt-Ausführung | -| `--trace` | `-t` | Ausführungs-Trace | -| `--variables` | `-v` | Variablen anzeigen | - -### Beispiele - -```bash -# Debug-Modus starten -dotnet run --project HypnoScript.CLI -- debug script.hyp - -# Mit Breakpoints -dotnet run --project HypnoScript.CLI -- debug script.hyp --breakpoints breakpoints.txt - -# Schritt-für-Schritt -dotnet run --project HypnoScript.CLI -- debug script.hyp --step - -# Mit Trace -dotnet run --project HypnoScript.CLI -- debug script.hyp --trace - -# Variablen anzeigen -dotnet run --project HypnoScript.CLI -- debug script.hyp --variables -``` - -## serve - Webserver starten - -Startet einen Webserver für HypnoScript-Anwendungen. - -### Syntax - -```bash -dotnet run --project HypnoScript.CLI -- serve [optionen] -``` - -### Optionen - -| Option | Kurzform | Beschreibung | -| ---------- | -------- | ------------------- | -| `--port` | `-p` | Port-Nummer | -| `--host` | `-h` | Host-Adresse | -| `--config` | `-c` | Konfigurationsdatei | -| `--ssl` | `-s` | SSL aktivieren | - -### Beispiele - -```bash -# Standard-Webserver -dotnet run --project HypnoScript.CLI -- serve - -# Mit spezifischem Port -dotnet run --project HypnoScript.CLI -- serve --port 8080 - -# Mit SSL -dotnet run --project HypnoScript.CLI -- serve --ssl - -# Mit Konfiguration -dotnet run --project HypnoScript.CLI -- serve --config server.json -``` - -## validate - Syntax prüfen - -Prüft die Syntax von HypnoScript-Dateien. - -### Syntax - -```bash -dotnet run --project HypnoScript.CLI -- validate [optionen] -``` - -### Optionen - -| Option | Kurzform | Beschreibung | -| ------------ | -------- | ------------------- | -| `--strict` | `-s` | Strikte Validierung | -| `--warnings` | `-w` | Warnungen anzeigen | -| `--output` | `-o` | Validierungs-Report | - -### Beispiele - -```bash -# Syntax prüfen -dotnet run --project HypnoScript.CLI -- validate script.hyp - -# Strikte Validierung -dotnet run --project HypnoScript.CLI -- validate script.hyp --strict - -# Mit Warnungen -dotnet run --project HypnoScript.CLI -- validate script.hyp --warnings - -# Report generieren -dotnet run --project HypnoScript.CLI -- validate script.hyp --output validation.json -``` - -## format - Code formatieren - -Formatiert HypnoScript-Code. - -### Syntax - -```bash -dotnet run --project HypnoScript.CLI -- format [optionen] -``` - -### Optionen - -| Option | Kurzform | Beschreibung | -| ------------ | -------- | ------------------------ | -| `--check` | `-c` | Nur prüfen, nicht ändern | -| `--in-place` | `-i` | Datei direkt ändern | -| `--output` | `-o` | Ausgabedatei | - -### Beispiele - -```bash -# Code formatieren -dotnet run --project HypnoScript.CLI -- format script.hyp - -# Nur prüfen -dotnet run --project HypnoScript.CLI -- format script.hyp --check - -# Direkt ändern -dotnet run --project HypnoScript.CLI -- format script.hyp --in-place - -# In neue Datei -dotnet run --project HypnoScript.CLI -- format script.hyp --output formatted.hyp -``` - -## lint - Code-Analyse - -Führt statische Code-Analyse durch. - -### Syntax - -```bash -dotnet run --project HypnoScript.CLI -- lint [optionen] -``` - -### Optionen - -| Option | Kurzform | Beschreibung | -| ------------ | -------- | ------------------- | -| `--rules` | `-r` | Lint-Regeln | -| `--severity` | `-s` | Mindest-Schweregrad | -| `--output` | `-o` | Lint-Report | - -### Beispiele - -```bash -# Code-Analyse -dotnet run --project HypnoScript.CLI -- lint script.hyp - -# Mit spezifischen Regeln -dotnet run --project HypnoScript.CLI -- lint script.hyp --rules "style,performance" - -# Nur Fehler -dotnet run --project HypnoScript.CLI -- lint script.hyp --severity error - -# Report generieren -dotnet run --project HypnoScript.CLI -- lint script.hyp --output lint-report.json -``` - -## package - Paket erstellen - -Erstellt ein ausführbares Paket. - -### Syntax - -```bash -dotnet run --project HypnoScript.CLI -- package [optionen] -``` - -### Optionen - -| Option | Kurzform | Beschreibung | -| ---------------- | -------- | --------------------------- | -| `--output` | `-o` | Ausgabedatei | -| `--runtime` | `-r` | Ziel-Runtime | -| `--dependencies` | `-d` | Abhängigkeiten einschließen | - -### Beispiele - -```bash -# Paket erstellen -dotnet run --project HypnoScript.CLI -- package script.hyp - -# Mit Runtime -dotnet run --project HypnoScript.CLI -- package script.hyp --runtime win-x64 - -# Mit Abhängigkeiten -dotnet run --project HypnoScript.CLI -- package script.hyp --dependencies - -# Spezifische Ausgabe -dotnet run --project HypnoScript.CLI -- package script.hyp --output myapp.exe -``` - -## Globale Optionen - -Alle Befehle unterstützen diese globalen Optionen: - -| Option | Kurzform | Beschreibung | -| ------------- | -------- | ------------------------------------ | -| `--help` | `-h` | Hilfe anzeigen | -| `--version` | `-V` | Version anzeigen | -| `--verbose` | `-v` | Detaillierte Ausgabe | -| `--quiet` | `-q` | Minimale Ausgabe | -| `--config` | `-c` | Konfigurationsdatei | -| `--log-level` | `-l` | Log-Level (debug, info, warn, error) | - -## Konfigurationsdatei - -Die CLI kann über eine `hypnoscript.config.json` konfiguriert werden: - -```json -{ - "defaultOutput": "console", - "enableDebug": false, - "logLevel": "info", - "timeout": 30000, - "maxMemory": 512, - "testFramework": { - "autoRun": true, - "reportFormat": "detailed" - }, - "server": { - "port": 8080, - "host": "localhost" - }, - "formatting": { - "indentSize": 2, - "maxLineLength": 80 - }, - "linting": { - "rules": ["style", "performance", "security"], - "severity": "warning" - } -} -``` - -## Umgebungsvariablen - -| Variable | Beschreibung | -| ----------------------- | ------------------------ | -| `HYPNOSCRIPT_HOME` | Installationsverzeichnis | -| `HYPNOSCRIPT_LOG_LEVEL` | Log-Level | -| `HYPNOSCRIPT_CONFIG` | Konfigurationsdatei | -| `HYPNOSCRIPT_TIMEOUT` | Standard-Timeout | - -## Beispiele für komplexe Workflows - -### Entwicklungsworkflow - -```bash -# 1. Syntax prüfen -dotnet run --project HypnoScript.CLI -- validate script.hyp - -# 2. Code formatieren -dotnet run --project HypnoScript.CLI -- format script.hyp --in-place - -# 3. Lint-Analyse -dotnet run --project HypnoScript.CLI -- lint script.hyp - -# 4. Tests ausführen -dotnet run --project HypnoScript.CLI -- test *.hyp - -# 5. Programm ausführen -dotnet run --project HypnoScript.CLI -- run script.hyp -``` - -### CI/CD-Pipeline - -```bash -# Build und Test -dotnet run --project HypnoScript.CLI -- build script.hyp --optimize -dotnet run --project HypnoScript.CLI -- test *.hyp --format json --output test-results.json -dotnet run --project HypnoScript.CLI -- lint script.hyp --severity error - -# Deployment -dotnet run --project HypnoScript.CLI -- package script.hyp --runtime linux-x64 -dotnet run --project HypnoScript.CLI -- serve --port 8080 --ssl -``` - -### Debugging-Workflow - -```bash -# 1. Syntax prüfen -dotnet run --project HypnoScript.CLI -- validate script.hyp - -# 2. Debug-Modus mit Trace -dotnet run --project HypnoScript.CLI -- debug script.hyp --trace --variables - -# 3. Schritt-für-Schritt -dotnet run --project HypnoScript.CLI -- debug script.hyp --step -``` - -## Nächste Schritte - -- [Konfiguration](./configuration) - Erweiterte Konfiguration -- [Testing](./testing) - Test-Framework -- [Debugging](./debugging) - Debugging-Tools -- [Runtime-Features](./enterprise-features) - Runtime-Features - ---- - -**Beherrschst du die CLI-Befehle? Dann lerne die [Konfiguration](./configuration) kennen!** ⚙️ diff --git a/HypnoScript.Dokumentation/docs/cli/configuration.md b/HypnoScript.Dokumentation/docs/cli/configuration.md deleted file mode 100644 index 4472a82..0000000 --- a/HypnoScript.Dokumentation/docs/cli/configuration.md +++ /dev/null @@ -1,500 +0,0 @@ ---- -sidebar_position: 3 ---- - -# CLI-Konfiguration - -Die HypnoScript CLI kann über Konfigurationsdateien, Umgebungsvariablen und Kommandozeilenoptionen konfiguriert werden. - -## Konfigurationsdatei - -Die Hauptkonfigurationsdatei ist `hypnoscript.config.json` im Projektverzeichnis. - -### Grundlegende Konfiguration - -```json -{ - "defaultOutput": "console", - "enableDebug": false, - "logLevel": "info", - "timeout": 30000, - "maxMemory": 512, - "testFramework": { - "autoRun": true, - "reportFormat": "detailed" - }, - "server": { - "port": 8080, - "host": "localhost" - }, - "formatting": { - "indentSize": 2, - "maxLineLength": 80 - }, - "linting": { - "rules": ["style", "performance", "security"], - "severity": "warning" - } -} -``` - -### Erweiterte Konfiguration - -```json -{ - "defaultOutput": "console", - "enableDebug": false, - "logLevel": "info", - "timeout": 30000, - "maxMemory": 512, - "testFramework": { - "autoRun": true, - "reportFormat": "detailed", - "parallelExecution": true, - "coverage": { - "enabled": true, - "threshold": 80 - } - }, - "server": { - "port": 8080, - "host": "localhost", - "ssl": { - "enabled": false, - "certPath": "", - "keyPath": "" - }, - "cors": { - "enabled": true, - "origins": ["*"] - } - }, - "formatting": { - "indentSize": 2, - "maxLineLength": 80, - "useTabs": false, - "trimTrailingWhitespace": true, - "insertFinalNewline": true - }, - "linting": { - "rules": ["style", "performance", "security"], - "severity": "warning", - "ignorePatterns": ["node_modules/**", "dist/**"], - "customRules": [] - }, - "compilation": { - "target": "il", - "optimization": { - "enabled": true, - "level": "standard" - }, - "debug": { - "enabled": false, - "symbols": true - } - }, - "packaging": { - "includeDependencies": true, - "runtime": "win-x64", - "compression": true - }, - "monitoring": { - "metrics": { - "enabled": true, - "interval": 5000 - }, - "profiling": { - "enabled": false, - "output": "profile.json" - } - } -} -``` - -## Konfigurationsoptionen - -### Allgemeine Einstellungen - -| Option | Typ | Standard | Beschreibung | -| --------------- | ------- | --------- | ------------------------------------ | -| `defaultOutput` | string | "console" | Standard-Ausgabekanal | -| `enableDebug` | boolean | false | Debug-Modus aktivieren | -| `logLevel` | string | "info" | Log-Level (debug, info, warn, error) | -| `timeout` | number | 30000 | Timeout in Millisekunden | -| `maxMemory` | number | 512 | Maximaler Speicherverbrauch in MB | - -### Test-Framework - -| Option | Typ | Standard | Beschreibung | -| ---------------------------------- | ------- | ---------- | --------------------------- | -| `testFramework.autoRun` | boolean | true | Tests automatisch ausführen | -| `testFramework.reportFormat` | string | "detailed" | Test-Report-Format | -| `testFramework.parallelExecution` | boolean | true | Parallele Test-Ausführung | -| `testFramework.coverage.enabled` | boolean | false | Code-Coverage aktivieren | -| `testFramework.coverage.threshold` | number | 80 | Mindest-Coverage in Prozent | - -### Server-Konfiguration - -| Option | Typ | Standard | Beschreibung | -| --------------------- | ------- | ----------- | --------------------- | -| `server.port` | number | 8080 | Server-Port | -| `server.host` | string | "localhost" | Server-Host | -| `server.ssl.enabled` | boolean | false | SSL aktivieren | -| `server.ssl.certPath` | string | "" | SSL-Zertifikatspfad | -| `server.ssl.keyPath` | string | "" | SSL-Schlüsselpfad | -| `server.cors.enabled` | boolean | true | CORS aktivieren | -| `server.cors.origins` | array | ["*"] | Erlaubte CORS-Origins | - -### Formatierung - -| Option | Typ | Standard | Beschreibung | -| ----------------------------------- | ------- | -------- | ----------------------------- | -| `formatting.indentSize` | number | 2 | Einrückungsgröße | -| `formatting.maxLineLength` | number | 80 | Maximale Zeilenlänge | -| `formatting.useTabs` | boolean | false | Tabs statt Leerzeichen | -| `formatting.trimTrailingWhitespace` | boolean | true | Trailing Whitespace entfernen | -| `formatting.insertFinalNewline` | boolean | true | Finale Newline einfügen | - -### Linting - -| Option | Typ | Standard | Beschreibung | -| ------------------------ | ------ | ------------------------------------ | ------------------------- | -| `linting.rules` | array | ["style", "performance", "security"] | Lint-Regeln | -| `linting.severity` | string | "warning" | Mindest-Schweregrad | -| `linting.ignorePatterns` | array | [] | Zu ignorierende Dateien | -| `linting.customRules` | array | [] | Benutzerdefinierte Regeln | - -### Kompilierung - -| Option | Typ | Standard | Beschreibung | -| ---------------------------------- | ------- | ---------- | ---------------------------- | -| `compilation.target` | string | "il" | Kompilierungsziel (il, wasm) | -| `compilation.optimization.enabled` | boolean | true | Optimierungen aktivieren | -| `compilation.optimization.level` | string | "standard" | Optimierungslevel | -| `compilation.debug.enabled` | boolean | false | Debug-Informationen | -| `compilation.debug.symbols` | boolean | true | Debug-Symbole | - -### Packaging - -| Option | Typ | Standard | Beschreibung | -| ------------------------------- | ------- | --------- | --------------------------- | -| `packaging.includeDependencies` | boolean | true | Abhängigkeiten einschließen | -| `packaging.runtime` | string | "win-x64" | Ziel-Runtime | -| `packaging.compression` | boolean | true | Kompression aktivieren | - -### Monitoring - -| Option | Typ | Standard | Beschreibung | -| ------------------------------ | ------- | -------------- | ---------------------- | -| `monitoring.metrics.enabled` | boolean | true | Metriken aktivieren | -| `monitoring.metrics.interval` | number | 5000 | Metrik-Intervall in ms | -| `monitoring.profiling.enabled` | boolean | false | Profiling aktivieren | -| `monitoring.profiling.output` | string | "profile.json" | Profiling-Ausgabedatei | - -## Umgebungsvariablen - -### HypnoScript-spezifische Variablen - -| Variable | Beschreibung | Standard | -| ------------------------ | ------------------------ | ------------------------- | -| `HYPNOSCRIPT_HOME` | Installationsverzeichnis | - | -| `HYPNOSCRIPT_LOG_LEVEL` | Log-Level | "info" | -| `HYPNOSCRIPT_CONFIG` | Konfigurationsdatei | "hypnoscript.config.json" | -| `HYPNOSCRIPT_TIMEOUT` | Standard-Timeout | "30000" | -| `HYPNOSCRIPT_MAX_MEMORY` | Maximaler Speicher | "512" | - -### Plattform-spezifische Variablen - -| Variable | Beschreibung | -| ------------------------- | ------------------- | -| `HYPNOSCRIPT_SERVER_PORT` | Server-Port | -| `HYPNOSCRIPT_SERVER_HOST` | Server-Host | -| `HYPNOSCRIPT_SSL_CERT` | SSL-Zertifikatspfad | -| `HYPNOSCRIPT_SSL_KEY` | SSL-Schlüsselpfad | - -### Beispiel für Umgebungsvariablen - -```bash -# Linux/macOS -export HYPNOSCRIPT_HOME="/opt/hypnoscript" -export HYPNOSCRIPT_LOG_LEVEL="debug" -export HYPNOSCRIPT_CONFIG="./config.json" -export HYPNOSCRIPT_TIMEOUT="60000" -export HYPNOSCRIPT_MAX_MEMORY="1024" - -# Windows (PowerShell) -$env:HYPNOSCRIPT_HOME = "C:\Program Files\HypnoScript" -$env:HYPNOSCRIPT_LOG_LEVEL = "debug" -$env:HYPNOSCRIPT_CONFIG = ".\config.json" -$env:HYPNOSCRIPT_TIMEOUT = "60000" -$env:HYPNOSCRIPT_MAX_MEMORY = "1024" - -# Windows (CMD) -set HYPNOSCRIPT_HOME=C:\Program Files\HypnoScript -set HYPNOSCRIPT_LOG_LEVEL=debug -set HYPNOSCRIPT_CONFIG=.\config.json -set HYPNOSCRIPT_TIMEOUT=60000 -set HYPNOSCRIPT_MAX_MEMORY=1024 -``` - -## Konfigurationshierarchie - -Die CLI verwendet eine Hierarchie für Konfigurationswerte: - -1. **Kommandozeilenoptionen** (höchste Priorität) -2. **Umgebungsvariablen** -3. **Projekt-Konfigurationsdatei** (`hypnoscript.config.json`) -4. **Benutzer-Konfigurationsdatei** (`~/.hypnoscript/config.json`) -5. **System-Konfigurationsdatei** (`/etc/hypnoscript/config.json`) -6. **Standardwerte** (niedrigste Priorität) - -### Beispiel für Konfigurationshierarchie - -```bash -# 1. Kommandozeilenoption überschreibt alles -dotnet run --project HypnoScript.CLI -- run script.hyp --timeout 120 - -# 2. Umgebungsvariable überschreibt Konfigurationsdatei -export HYPNOSCRIPT_TIMEOUT=60 -dotnet run --project HypnoScript.CLI -- run script.hyp - -# 3. Projekt-Konfigurationsdatei -# hypnoscript.config.json: { "timeout": 30000 } - -# 4. Benutzer-Konfigurationsdatei -# ~/.hypnoscript/config.json: { "timeout": 60000 } - -# 5. System-Konfigurationsdatei -# /etc/hypnoscript/config.json: { "timeout": 300000 } -``` - -## Profilbasierte Konfiguration - -Sie können verschiedene Konfigurationsprofile für unterschiedliche Umgebungen erstellen: - -### Profil-Konfiguration - -```json -{ - "profiles": { - "development": { - "logLevel": "debug", - "enableDebug": true, - "timeout": 60000, - "testFramework": { - "autoRun": true, - "reportFormat": "detailed" - } - }, - "production": { - "logLevel": "warn", - "enableDebug": false, - "timeout": 30000, - "testFramework": { - "autoRun": false, - "reportFormat": "summary" - }, - "compilation": { - "optimization": { - "enabled": true, - "level": "aggressive" - } - } - }, - "testing": { - "logLevel": "info", - "testFramework": { - "autoRun": true, - "coverage": { - "enabled": true, - "threshold": 90 - } - } - } - } -} -``` - -### Profil verwenden - -```bash -# Profil über Umgebungsvariable -export HYPNOSCRIPT_PROFILE=production -dotnet run --project HypnoScript.CLI -- run script.hyp - -# Profil über Kommandozeile -dotnet run --project HypnoScript.CLI -- run script.hyp --profile production -``` - -## Erweiterte Konfigurationsszenarien - -### Multi-Environment Setup - -```json -{ - "environments": { - "local": { - "server": { - "port": 3000, - "host": "localhost" - }, - "database": { - "connectionString": "localhost:5432" - } - }, - "staging": { - "server": { - "port": 8080, - "host": "staging.example.com" - }, - "database": { - "connectionString": "staging-db:5432" - } - }, - "production": { - "server": { - "port": 443, - "host": "app.example.com", - "ssl": { - "enabled": true - } - }, - "database": { - "connectionString": "prod-db:5432" - } - } - } -} -``` - -### Team-Konfiguration - -```json -{ - "team": { - "codeStyle": { - "formatting": { - "indentSize": 2, - "maxLineLength": 100 - }, - "linting": { - "rules": ["style", "performance", "security"], - "severity": "error" - } - }, - "testing": { - "coverage": { - "enabled": true, - "threshold": 85 - }, - "parallelExecution": true - }, - "ci": { - "autoFormat": true, - "autoLint": true, - "requireTests": true - } - } -} -``` - -## Best Practices - -### Konfigurationsdatei organisieren - -```bash -project/ -├── config/ -│ ├── hypnoscript.config.json # Hauptkonfiguration -│ ├── development.config.json # Entwicklung -│ ├── staging.config.json # Staging -│ └── production.config.json # Produktion -├── scripts/ -│ ├── setup-dev.sh # Entwicklung einrichten -│ └── setup-prod.sh # Produktion einrichten -└── .env.example # Umgebungsvariablen-Beispiel -``` - -### Sichere Konfiguration - -```json -{ - "security": { - "secrets": { - "useEnvVars": true, - "envPrefix": "HYPNOSCRIPT_" - }, - "ssl": { - "enabled": true, - "certPath": "${SSL_CERT_PATH}", - "keyPath": "${SSL_KEY_PATH}" - } - } -} -``` - -### Performance-Optimierung - -```json -{ - "performance": { - "compilation": { - "optimization": { - "enabled": true, - "level": "aggressive" - }, - "parallel": true - }, - "runtime": { - "gc": { - "enabled": true, - "interval": 1000 - } - } - } -} -``` - -## Troubleshooting - -### Häufige Konfigurationsprobleme - -1. **Konfigurationsdatei wird nicht gefunden** - - ```bash - # Prüfen Sie den Pfad - ls -la hypnoscript.config.json - - # Verwenden Sie absolute Pfade - export HYPNOSCRIPT_CONFIG="/absolute/path/config.json" - ``` - -2. **Umgebungsvariablen werden nicht erkannt** - - ```bash - # Prüfen Sie die Variablen - echo $HYPNOSCRIPT_LOG_LEVEL - - # Starten Sie die Shell neu - source ~/.bashrc - ``` - -3. **Konflikte zwischen Profilen** - - ```bash - # Profil explizit setzen - export HYPNOSCRIPT_PROFILE=development - - # Profil über Kommandozeile - dotnet run --project HypnoScript.CLI -- run script.hyp --profile development - ``` - -## Nächste Schritte - -- [Testing](../testing/overview) - Test-Framework-Konfiguration -- [Debugging](../debugging/tools) - Debugging-Tools -- [Runtime-Features](../enterprise/features) - Runtime-Konfiguration - ---- - -**Konfiguration gemeistert? Dann lerne das [Test-Framework](../testing/overview) kennen!** 🧪 diff --git a/HypnoScript.Dokumentation/docs/cli/debugging.md b/HypnoScript.Dokumentation/docs/cli/debugging.md deleted file mode 100644 index e3b9711..0000000 --- a/HypnoScript.Dokumentation/docs/cli/debugging.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: CLI Debugging ---- - -# CLI Debugging - -Die HypnoScript CLI bietet zahlreiche Optionen für Debugging und Fehleranalyse. - -## Debug- und Verbose-Optionen - -- `--debug`: Aktiviert Debug-Ausgaben (z.B. Stacktraces, interne Statusmeldungen) -- `--verbose`: Zeigt zusätzliche Details zu Token, AST und Ausführung - -## Wichtige CLI-Befehle - -- `run [--debug] [--verbose]`: Skript ausführen -- `test [--debug] [--verbose]`: Tests ausführen und Assertion-Fehler anzeigen -- `profile [--debug] [--verbose]`: Profiling (geplant) -- `benchmark [--debug] [--verbose]`: Benchmarking (geplant) -- `optimize [--debug] [--verbose]`: Code-Optimierung (geplant) - -## Debug-Ausgaben interpretieren - -- Assertion-Fehler werden klar hervorgehoben -- Fehlerausgaben enthalten ggf. Stacktraces (bei `--debug`) -- Zusammenfassungen am Ende zeigen, wie viele Tests bestanden/fehlgeschlagen sind - -## Beispiel - -```bash -dotnet run --project HypnoScript.CLI -- test test_basic.hyp --debug --verbose -``` - -## Tipps - -- Nutzen Sie die CLI-Optionen gezielt, um Fehlerquellen schnell zu identifizieren -- Kombinieren Sie Debug- und Verbose-Flags für maximale Transparenz diff --git a/HypnoScript.Dokumentation/docs/cli/overview.md b/HypnoScript.Dokumentation/docs/cli/overview.md deleted file mode 100644 index 7b395b0..0000000 --- a/HypnoScript.Dokumentation/docs/cli/overview.md +++ /dev/null @@ -1,170 +0,0 @@ ---- -sidebar_position: 1 ---- - -# CLI Übersicht - -Die HypnoScript Command Line Interface (CLI) bietet eine vollständige Entwicklungsumgebung für HypnoScript-Programme mit umfangreichen Features für Entwicklung, Testing und Deployment. - -## Installation - -```bash -# Repository klonen -git clone https://github.com/Kink-Development-Group/hyp-runtime.git -cd hyp-runtime - -# Projekt bauen -dotnet build - -# CLI verwenden -dotnet run --project HypnoScript.CLI -- --help -``` - -## Installation via Paketmanager - -### Windows (winget) - -```powershell -winget install HypnoScript.HypnoScript -``` - -### Linux (APT) - -```bash -sudo apt update -sudo apt install hypnoscript -``` - -## Automatisierte Releases & Paketmanager - -Die aktuellen Installationspakete (ZIP für Windows/winget, .deb für Linux/APT) werden bei jedem Release automatisch gebaut und als Artefakte auf GitHub bereitgestellt: - -- [GitHub Releases](https://github.com/Kink-Development-Group/hyp-runtime/releases) - -### Installation mit winget (Windows) - -```powershell -winget install HypnoScript.HypnoScript -``` - -### Installation mit APT (Linux) - -```bash -sudo apt update -sudo apt install hypnoscript -``` - -## Grundlegende Verwendung - -```bash -# Programm ausführen -dotnet run --project HypnoScript.CLI -- run programm.hyp - -# Version anzeigen -dotnet run --project HypnoScript.CLI -- --version - -# Hilfe anzeigen -dotnet run --project HypnoScript.CLI -- --help -``` - -## Verfügbare Befehle - -| Befehl | Beschreibung | Beispiel | -| ---------- | -------------------- | --------------------- | -| `run` | Programm ausführen | `run script.hyp` | -| `test` | Tests ausführen | `test *.hyp` | -| `build` | Programm kompilieren | `build script.hyp` | -| `debug` | Debug-Modus | `debug script.hyp` | -| `serve` | Webserver starten | `serve --port 8080` | -| `validate` | Syntax prüfen | `validate script.hyp` | - -## Globale Optionen - -| Option | Kurzform | Beschreibung | -| ----------- | -------- | -------------------- | -| `--verbose` | `-v` | Detaillierte Ausgabe | -| `--quiet` | `-q` | Minimale Ausgabe | -| `--config` | `-c` | Konfigurationsdatei | -| `--output` | `-o` | Ausgabedatei | -| `--timeout` | `-t` | Timeout in Sekunden | - -## Konfiguration - -### Konfigurationsdatei (hypnoscript.config.json) - -```json -{ - "defaultOutput": "console", - "enableDebug": false, - "logLevel": "info", - "timeout": 30000, - "maxMemory": 512, - "testFramework": { - "autoRun": true, - "reportFormat": "detailed" - }, - "server": { - "port": 8080, - "host": "localhost" - } -} -``` - -### Umgebungsvariablen - -```bash -# Windows -set HYPNOSCRIPT_HOME=C:\path\to\hyp-runtime -set HYPNOSCRIPT_LOG_LEVEL=debug - -# Linux/macOS -export HYPNOSCRIPT_HOME=/path/to/hyp-runtime -export HYPNOSCRIPT_LOG_LEVEL=debug -``` - -## Beispiele - -### Einfaches Programm ausführen - -```bash -# Programm erstellen -echo 'Focus { entrance { observe "Hallo Welt!"; } } Relax;' > hello.hyp - -# Programm ausführen -dotnet run --project HypnoScript.CLI -- run hello.hyp -``` - -### Mit Parametern - -```bash -# Programm mit Argumenten -dotnet run --project HypnoScript.CLI -- run script.hyp --arg1 value1 --arg2 value2 -``` - -### Debug-Modus - -```bash -# Mit Debug-Informationen -dotnet run --project HypnoScript.CLI -- debug script.hyp --verbose -``` - -### Tests ausführen - -```bash -# Alle Tests im Verzeichnis -dotnet run --project HypnoScript.CLI -- test *.hyp - -# Spezifische Test-Datei -dotnet run --project HypnoScript.CLI -- test test_math.hyp -``` - -## Nächste Schritte - -- [CLI-Befehle](./commands) - Detaillierte Befehlsreferenz -- [Konfiguration](./configuration) - Erweiterte Konfiguration -- [Testing](./testing) - Test-Framework -- [Debugging](./debugging) - Debugging-Tools - ---- - -**Bereit für die detaillierte Befehlsreferenz?** 🚀 diff --git a/HypnoScript.Dokumentation/docs/cli/testing.md b/HypnoScript.Dokumentation/docs/cli/testing.md deleted file mode 100644 index 017d8be..0000000 --- a/HypnoScript.Dokumentation/docs/cli/testing.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: CLI Testing ---- - -# CLI Testing - -This page will document CLI testing features. Content coming soon. diff --git a/HypnoScript.Dokumentation/docs/examples/basic-examples.md b/HypnoScript.Dokumentation/docs/examples/basic-examples.md deleted file mode 100644 index 176703c..0000000 --- a/HypnoScript.Dokumentation/docs/examples/basic-examples.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Basic Examples ---- - -# Basic Examples - -This page will contain basic usage examples for HypnoScript. Content coming soon. diff --git a/HypnoScript.Dokumentation/docs/getting-started/cli-basics.md b/HypnoScript.Dokumentation/docs/getting-started/cli-basics.md deleted file mode 100644 index 0f8c724..0000000 --- a/HypnoScript.Dokumentation/docs/getting-started/cli-basics.md +++ /dev/null @@ -1,521 +0,0 @@ ---- -title: CLI Basics ---- - -# CLI Basics - -The HypnoScript Command Line Interface (CLI) is your primary tool for working with HypnoScript. This guide covers all the essential commands and options you need to know. - -## Overview - -The HypnoScript CLI provides a comprehensive set of commands for: - -- Running scripts -- Analyzing code quality -- Measuring performance -- Generating documentation -- Managing configuration -- Testing and validation - -## Getting Help - -### General Help - -```bash -# Show main help -hyp --help - -# Show version information -hyp --version -``` - -### Command-Specific Help - -```bash -# Help for specific commands -hyp run --help -hyp lint --help -hyp benchmark --help -hyp profile --help -hyp optimize --help -hyp docs --help -hyp config --help -``` - -## Core Commands - -### Running Scripts - -The `run` command executes HypnoScript files: - -```bash -# Basic script execution -hyp run script.hyp - -# Run with specific arguments -hyp run script.hyp --arg1 value1 --arg2 value2 - -# Run with verbose output -hyp run script.hyp --verbose - -# Run with debug information -hyp run script.hyp --debug - -# Run and save output to file -hyp run script.hyp --output result.txt -``` - -**Options:** - -- `--verbose, -v`: Enable verbose logging -- `--debug, -d`: Enable debug mode -- `--output, -o `: Save output to specified file -- `--timeout `: Set execution timeout -- `--memory-limit `: Set memory usage limit - -### Code Analysis (Linting) - -The `lint` command analyzes your code for potential issues: - -```bash -# Basic linting -hyp lint script.hyp - -# Lint with detailed output -hyp lint script.hyp --verbose - -# Lint multiple files -hyp lint *.hyp - -# Lint with specific rules -hyp lint script.hyp --strict - -# Generate lint report -hyp lint script.hyp --output lint-report.json -``` - -**Options:** - -- `--verbose, -v`: Show detailed analysis -- `--strict`: Enable strict mode (more warnings) -- `--output, -o `: Save report to file -- `--format `: Output format (text, json, xml) - -**What it checks:** - -- Syntax errors -- Type mismatches -- Undefined variables -- Unused variables -- Potential runtime issues -- Code style violations - -### Performance Benchmarking - -The `benchmark` command measures script performance: - -```bash -# Basic benchmarking -hyp benchmark script.hyp - -# Benchmark with multiple iterations -hyp benchmark script.hyp --iterations 100 - -# Benchmark with warm-up runs -hyp benchmark script.hyp --warmup 10 --iterations 50 - -# Detailed performance analysis -hyp benchmark script.hyp --detailed - -# Save benchmark results -hyp benchmark script.hyp --output benchmark.json -``` - -**Options:** - -- `--iterations, -i `: Number of test iterations -- `--warmup `: Number of warm-up runs -- `--detailed, -d`: Show detailed statistics -- `--output, -o `: Save results to file -- `--timeout `: Timeout per iteration - -### Performance Profiling - -The `profile` command provides detailed performance analysis: - -```bash -# Basic profiling -hyp profile script.hyp - -# Profile with memory tracking -hyp profile script.hyp --memory - -# Profile with call stack analysis -hyp profile script.hyp --call-stack - -# Generate profiling report -hyp profile script.hyp --output profile.html -``` - -**Options:** - -- `--memory, -m`: Track memory usage -- `--call-stack, -c`: Analyze function calls -- `--detailed, -d`: Detailed profiling data -- `--output, -o `: Save profile report -- `--format `: Report format (text, html, json) - -### Code Optimization - -The `optimize` command provides optimization suggestions: - -```bash -# Basic optimization analysis -hyp optimize script.hyp - -# Detailed optimization report -hyp optimize script.hyp --detailed - -# Generate optimization suggestions -hyp optimize script.hyp --suggestions - -# Save optimization report -hyp optimize script.hyp --output optimize.json -``` - -**Options:** - -- `--detailed, -d`: Detailed analysis -- `--suggestions, -s`: Show optimization suggestions -- `--output, -o `: Save report to file -- `--format `: Output format - -### Documentation Generation - -The `docs` command generates documentation from your scripts: - -```bash -# Generate basic documentation -hyp docs script.hyp - -# Generate HTML documentation -hyp docs script.hyp --format html - -# Generate documentation with examples -hyp docs script.hyp --include-examples - -# Generate documentation for multiple files -hyp docs *.hyp --output docs/ - -# Generate API documentation -hyp docs script.hyp --api -``` - -**Options:** - -- `--format `: Output format (markdown, html, pdf) -- `--include-examples, -e`: Include code examples -- `--api, -a`: Generate API documentation -- `--output, -o `: Output directory -- `--template `: Custom template file - -### Configuration Management - -The `config` command manages HypnoScript configuration: - -```bash -# Show current configuration -hyp config show - -# Get specific setting -hyp config get logging.level - -# Set configuration value -hyp config set logging.level DEBUG - -# Reset configuration to defaults -hyp config reset - -# Export configuration -hyp config export --output config.json - -# Import configuration -hyp config import config.json -``` - -**Subcommands:** - -- `show`: Display current configuration -- `get `: Get specific configuration value -- `set `: Set configuration value -- `reset`: Reset to default configuration -- `export`: Export configuration to file -- `import`: Import configuration from file - -## Advanced Usage - -### Batch Processing - -Process multiple files at once: - -```bash -# Run multiple scripts -hyp run *.hyp - -# Lint all scripts in directory -hyp lint src/**/*.hyp - -# Benchmark all test scripts -hyp benchmark tests/*.hyp --iterations 10 - -# Generate docs for all scripts -hyp docs src/**/*.hyp --output docs/ -``` - -### Script Arguments - -Pass arguments to your scripts: - -```bash -# Pass named arguments -hyp run script.hyp --name "John" --age 30 - -# Pass positional arguments -hyp run script.hyp arg1 arg2 arg3 - -# Pass complex data -hyp run script.hyp --config config.json --data data.csv -``` - -### Output Redirection - -```bash -# Save output to file -hyp run script.hyp > output.txt - -# Save errors to file -hyp run script.hyp 2> errors.log - -# Save both output and errors -hyp run script.hyp > output.txt 2>&1 - -# Pipe output to another command -hyp run script.hyp | grep "ERROR" -``` - -### Environment Variables - -Set environment variables for script execution: - -```bash -# Set single variable -DEBUG=true hyp run script.hyp - -# Set multiple variables -DEBUG=true LOG_LEVEL=INFO hyp run script.hyp - -# Use environment file -hyp run script.hyp --env-file .env -``` - -## Configuration - -### Global Configuration - -HypnoScript uses a global configuration file: - -**Location:** - -- Windows: `%APPDATA%\HypnoScript\config.json` -- Linux/macOS: `~/.config/hypnoscript/config.json` - -**Example configuration:** - -```json -{ - "logging": { - "level": "INFO", - "format": "text" - }, - "runtime": { - "timeout": 300, - "memoryLimit": 512 - }, - "cli": { - "defaultFormat": "text", - "colorOutput": true - } -} -``` - -### Project Configuration - -Create a `hypnoscript.json` file in your project root: - -```json -{ - "name": "my-project", - "version": "1.0.0", - "scripts": { - "test": "hyp run tests/*.hyp", - "lint": "hyp lint src/**/*.hyp", - "docs": "hyp docs src/**/*.hyp --output docs/" - }, - "config": { - "logging": { - "level": "DEBUG" - } - } -} -``` - -## Troubleshooting - -### Common Issues - -1. **"Command not found"**: - - ```bash - # Check installation - hyp --version - - # Reinstall if needed - winget install HypnoScript.HypnoScript - ``` - -2. **Permission errors**: - - ```bash - # On Linux/macOS - chmod +x script.hyp - - # Check file permissions - ls -la script.hyp - ``` - -3. **Script execution fails**: - - ```bash - # Check for syntax errors - hyp lint script.hyp - - # Run with debug mode - hyp run script.hyp --debug - ``` - -4. **Performance issues**: - - ```bash - # Profile the script - hyp profile script.hyp --memory - - # Check for memory leaks - hyp benchmark script.hyp --iterations 100 - ``` - -### Debug Mode - -Enable debug mode for detailed information: - -```bash -# Enable debug logging -hyp run script.hyp --debug - -# Set debug environment variable -DEBUG=true hyp run script.hyp - -# Use verbose output -hyp run script.hyp --verbose -``` - -### Log Files - -HypnoScript creates log files for debugging: - -**Location:** - -- Windows: `%TEMP%\hypnoscript\logs\` -- Linux/macOS: `/tmp/hypnoscript/logs/` - -**Log levels:** - -- `ERROR`: Error messages only -- `WARNING`: Warnings and errors -- `INFO`: General information (default) -- `DEBUG`: Detailed debugging information -- `TRACE`: Very detailed tracing - -## Best Practices - -### 1. Use Consistent Naming - -```bash -# Good -hyp run user-authentication.hyp -hyp lint data-processing.hyp - -# Avoid -hyp run script1.hyp -hyp lint temp.hyp -``` - -### 2. Organize Your Projects - -``` -project/ -├── src/ -│ ├── main.hyp -│ └── utils.hyp -├── tests/ -│ ├── test-main.hyp -│ └── test-utils.hyp -├── docs/ -├── hypnoscript.json -└── README.md -``` - -### 3. Use Configuration Files - -```bash -# Create project configuration -hyp config export --output hypnoscript.json - -# Use project-specific settings -hyp run script.hyp --config hypnoscript.json -``` - -### 4. Automate Common Tasks - -Create shell scripts or batch files: - -```bash -#!/bin/bash -# build.sh -hyp lint src/**/*.hyp -hyp run tests/*.hyp -hyp docs src/**/*.hyp --output docs/ -``` - -### 5. Version Control Integration - -```bash -# Pre-commit hooks -hyp lint staged-files.hyp -hyp run tests/*.hyp - -# CI/CD integration -hyp benchmark critical-script.hyp --iterations 100 -hyp profile performance-test.hyp -``` - -## Conclusion - -The HypnoScript CLI provides powerful tools for development, testing, and deployment. By mastering these commands, you can: - -- Write better code with linting and optimization -- Measure and improve performance -- Generate comprehensive documentation -- Manage configuration effectively -- Automate your development workflow - -Start with the basic commands and gradually explore the advanced features as you become more comfortable with HypnoScript development. diff --git a/HypnoScript.Dokumentation/docs/getting-started/hello-world.md b/HypnoScript.Dokumentation/docs/getting-started/hello-world.md deleted file mode 100644 index 533254d..0000000 --- a/HypnoScript.Dokumentation/docs/getting-started/hello-world.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Hello World ---- - -# Hello World - -This page will provide a Hello World example for HypnoScript. Content coming soon. diff --git a/HypnoScript.Dokumentation/docs/getting-started/installation.md b/HypnoScript.Dokumentation/docs/getting-started/installation.md deleted file mode 100644 index 421b9e2..0000000 --- a/HypnoScript.Dokumentation/docs/getting-started/installation.md +++ /dev/null @@ -1,269 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Installation - -Lerne, wie du HypnoScript auf deinem System installierst und einrichtest. - -## Voraussetzungen - -### Systemanforderungen - -- **Betriebssystem**: Windows 10+, macOS 10.15+, oder Linux (Ubuntu 18.04+, CentOS 7+) -- **.NET**: .NET 8.0 SDK oder höher -- **RAM**: Mindestens 512 MB verfügbarer RAM -- **Festplatte**: 100 MB freier Speicherplatz - -### .NET Installation - -HypnoScript benötigt .NET 8.0 oder höher. Falls noch nicht installiert: - -#### Windows - -```powershell -# Download von Microsoft -winget install Microsoft.DotNet.SDK.8 -# oder -choco install dotnet-sdk -``` - -#### macOS - -```bash -# Mit Homebrew -brew install dotnet - -# Oder Download von Microsoft -curl -sSL https://dot.net/v1/dotnet-install.sh | bash -``` - -#### Linux (Ubuntu/Debian) - -```bash -# Repository hinzufügen -wget https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/packages-microsoft-prod.deb -O packages-microsoft-prod.deb -sudo dpkg -i packages-microsoft-prod.deb -rm packages-microsoft-prod.deb - -# .NET installieren -sudo apt-get update -sudo apt-get install -y dotnet-sdk-8.0 -``` - -## Installation von HypnoScript - -### Option 1: Aus dem Repository (Empfohlen) - -```bash -# Repository klonen -git clone https://github.com/Kink-Development-Group/hyp-runtime.git -cd hyp-runtime - -# Projekt bauen -dotnet build - -# Testen der Installation -dotnet run --project HypnoScript.CLI -- --help -``` - -### Option 2: Release-Download - -1. Gehe zu [GitHub Releases](https://github.com/Kink-Development-Group/hyp-runtime/releases) -2. Lade die neueste Version für dein Betriebssystem herunter -3. Entpacke das Archiv -4. Führe die ausführbare Datei aus - -### Option 3: Globale Installation (Entwicklung) - -```bash -# Repository klonen -git clone https://github.com/Kink-Development-Group/hyp-runtime.git -cd hyp-runtime - -# Globale Installation -dotnet tool install --global --add-source ./HypnoScript.CLI/bin/Debug/net8.0 HypnoScript.CLI - -# Oder mit dotnet run -dotnet run --project HypnoScript.CLI -- run example.hyp -``` - -## Verifikation der Installation - -### Test der Installation - -```bash -# Version anzeigen -dotnet run --project HypnoScript.CLI -- --version - -# Hilfe anzeigen -dotnet run --project HypnoScript.CLI -- --help - -# Einfaches Test-Programm -echo 'Focus { entrance { observe "Installation erfolgreich!"; } } Relax;' > test.hyp -dotnet run --project HypnoScript.CLI -- run test.hyp -``` - -### Erwartete Ausgabe - -``` -HypnoScript CLI v1.0.0 -Installation erfolgreich! -``` - -## Konfiguration - -### Umgebungsvariablen - -```bash -# Windows (PowerShell) -$env:HYPNOSCRIPT_HOME = "C:\path\to\hyp-runtime" - -# macOS/Linux -export HYPNOSCRIPT_HOME="/path/to/hyp-runtime" -``` - -### Konfigurationsdatei - -Erstelle eine `hypnoscript.config.json` im Projektverzeichnis: - -```json -{ - "defaultOutput": "console", - "enableDebug": false, - "logLevel": "info", - "timeout": 30000, - "maxMemory": 512 -} -``` - -## IDE-Integration - -### Visual Studio Code - -1. Installiere die C# Extension -2. Öffne das HypnoScript-Projekt -3. Erstelle eine `.vscode/launch.json`: - -```json -{ - "version": "0.2.0", - "configurations": [ - { - "name": "Run HypnoScript", - "type": "coreclr", - "request": "launch", - "preLaunchTask": "build", - "program": "${workspaceFolder}/HypnoScript.CLI/bin/Debug/net8.0/HypnoScript.CLI.dll", - "args": ["run", "${file}"], - "cwd": "${workspaceFolder}", - "console": "internalConsole", - "stopAtEntry": false - } - ] -} -``` - -### JetBrains Rider - -1. Öffne das Projekt in Rider -2. Konfiguriere Run Configurations -3. Setze die CLI als Startup Project - -## Troubleshooting - -### Häufige Probleme - -#### .NET nicht gefunden - -```bash -# Prüfe .NET Installation -dotnet --version - -# Falls nicht installiert, siehe .NET Installation oben -``` - -#### Build-Fehler - -```bash -# Dependencies wiederherstellen -dotnet restore - -# Clean und Rebuild -dotnet clean -dotnet build -``` - -#### Berechtigungsfehler (Linux/macOS) - -```bash -# Ausführungsrechte setzen -chmod +x HypnoScript.CLI/bin/Debug/net8.0/HypnoScript.CLI - -# Oder mit sudo (nicht empfohlen) -sudo dotnet run --project HypnoScript.CLI -- run test.hyp -``` - -#### Pfad-Probleme - -```bash -# Prüfe aktuelles Verzeichnis -pwd - -# Navigiere zum Projektverzeichnis -cd /path/to/hyp-runtime - -# Prüfe Projektstruktur -ls -la -``` - -### Support - -Bei Problemen: - -1. **GitHub Issues**: [Issues erstellen](https://github.com/Kink-Development-Group/hyp-runtime/issues) -2. **Discussions**: [Community-Diskussionen](https://github.com/Kink-Development-Group/hyp-runtime/discussions) -3. **Dokumentation**: Siehe [Troubleshooting Guide](../development/debugging) - -## Nächste Schritte - -- [Schnellstart-Guide](./quick-start) - Erstelle dein erstes HypnoScript-Programm -- [Hello World](./hello-world) - Lerne die Grundlagen -- [CLI-Grundlagen](./cli-basics) - Verstehe die Kommandozeilen-Tools -- [Sprachreferenz](../language-reference/syntax) - Lerne die Syntax - ---- - -**Installation erfolgreich? Dann lass uns mit dem [Schnellstart-Guide](./quick-start) beginnen!** 🚀 - -## Automatisierte Releases & Paketmanager - -Bei jedem neuen Release werden automatisch folgende Pakete gebaut und als Release-Artefakte auf GitHub bereitgestellt: - -- **Windows ZIP**: Für die Installation via winget oder manuell -- **Linux .deb**: Für die Installation via APT oder manuell -- **SHA256-Hash**: Für das winget-Manifest - -Die jeweils aktuellen Pakete findest du unter [GitHub Releases](https://github.com/Kink-Development-Group/hyp-runtime/releases). - -### Windows (winget) - -```powershell -winget install HypnoScript.HypnoScript -``` - -Das winget-Manifest wird nach jedem Release aktualisiert. Die SHA256-Prüfsumme findest du im Release oder im Workflow-Log. - -### Linux (APT) - -```bash -sudo apt update -sudo apt install hypnoscript -``` - -Alternativ kann das .deb-Paket direkt aus dem Release heruntergeladen und installiert werden: - -```bash -sudo dpkg -i hypnoscript_1.0.0_amd64.deb -sudo apt-get install -f # fehlende Abhängigkeiten ggf. nachinstallieren -``` diff --git a/HypnoScript.Dokumentation/docs/getting-started/quick-start.md b/HypnoScript.Dokumentation/docs/getting-started/quick-start.md deleted file mode 100644 index 0a25c68..0000000 --- a/HypnoScript.Dokumentation/docs/getting-started/quick-start.md +++ /dev/null @@ -1,326 +0,0 @@ ---- -title: Quick Start ---- - -# Quick Start Guide - -Get up and running with HypnoScript in minutes! This guide will walk you through installing HypnoScript and creating your first script. - -## Prerequisites - -- **Operating System**: Windows 10/11, Linux, or macOS -- **.NET Runtime**: .NET 8.0 or later -- **Memory**: At least 512MB RAM -- **Disk Space**: 50MB free space - -## Installation - -### Windows - -1. **Using Winget (Recommended)**: - - ```bash - winget install HypnoScript.HypnoScript - ``` - -2. **Manual Installation**: - - Download the latest release from [GitHub Releases](https://github.com/Kink-Development-Group/hyp-runtime/releases) - - Extract the ZIP file to a directory of your choice - - Add the directory to your system PATH - -### Linux/macOS - -1. **Using Package Manager**: - - ```bash - # Ubuntu/Debian - sudo apt-get install hypnoscript - - # macOS (using Homebrew) - brew install hypnoscript - ``` - -2. **Manual Installation**: - ```bash - # Download and install - curl -L https://github.com/Kink-Development-Group/hyp-runtime/releases/latest/download/hypnoscript-linux-x64.tar.gz | tar -xz - sudo mv hypnoscript /usr/local/bin/ - ``` - -## Verify Installation - -Open a terminal or command prompt and run: - -```bash -hyp --version -``` - -You should see output similar to: - -``` -HypnoScript CLI v1.0.0 -``` - -## Your First Script - -### 1. Create a Simple Script - -Create a file named `hello.hyp` with the following content: - -```hypno -Focus { - // Display a welcome message - Observe("Welcome to HypnoScript!"); - - // Define some variables - induce name: string = "World"; - induce greeting: string = "Hello, " + name + "!"; - - // Display the greeting - Observe(greeting); - - // Perform a simple calculation - induce number: number = 42; - induce result: number = number * 2; - Observe("The answer is: " + result); - - // Use a built-in function - induce currentTime: string = GetCurrentTime(); - Observe("Current time: " + currentTime); -} Relax -``` - -### 2. Run Your Script - -```bash -hyp run hello.hyp -``` - -You should see output similar to: - -``` -Welcome to HypnoScript! -Hello, World! -The answer is: 84 -Current time: 2024-01-15 14:30:25 -``` - -## Understanding the Basics - -### Script Structure - -Every HypnoScript file follows this basic structure: - -```hypno -Focus { - // Your code goes here - // This is the main execution block -} Relax -``` - -- `Focus { }` - Marks the beginning of your script execution -- `Relax` - Marks the end of your script execution - -### Variables and Types - -HypnoScript supports several data types: - -```hypno -Focus { - // String variables - induce message: string = "Hello, World!"; - - // Number variables - induce count: number = 42; - induce price: number = 19.99; - - // Boolean variables - induce isActive: boolean = true; - - // Array variables - induce numbers: number[] = [1, 2, 3, 4, 5]; - induce names: string[] = ["Alice", "Bob", "Charlie"]; - - // Record variables (similar to objects) - induce user: record = { - "name": "John Doe", - "age": 30, - "email": "john@example.com" - }; -} Relax -``` - -### Basic Operations - -```hypno -Focus { - // Arithmetic operations - induce a: number = 10; - induce b: number = 5; - induce sum: number = a + b; - induce difference: number = a - b; - induce product: number = a * b; - induce quotient: number = a / b; - - // String operations - induce firstName: string = "John"; - induce lastName: string = "Doe"; - induce fullName: string = firstName + " " + lastName; - - // Comparison operations - induce isEqual: boolean = a == b; - induce isGreater: boolean = a > b; - induce isLessOrEqual: boolean = a <= b; - - // Logical operations - induce condition1: boolean = true; - induce condition2: boolean = false; - induce bothTrue: boolean = condition1 && condition2; - induce eitherTrue: boolean = condition1 || condition2; -} Relax -``` - -## Next Steps - -### 1. Explore Built-in Functions - -HypnoScript comes with many built-in functions: - -```hypno -Focus { - // String functions - induce text: string = "Hello, World!"; - induce length: number = Length(text); - induce upper: string = ToUpperCase(text); - induce lower: string = ToLowerCase(text); - - // Math functions - induce number: number = -5.7; - induce absolute: number = Abs(number); - induce rounded: number = Round(number); - induce squareRoot: number = Sqrt(16); - - // Array functions - induce numbers: number[] = [3, 1, 4, 1, 5]; - induce count: number = Length(numbers); - induce sorted: number[] = Sort(numbers); - induce max: number = Max(numbers); -} Relax -``` - -### 2. Create Functions - -```hypno -Focus { - // Define a simple function - function Greet(name: string): string { - return "Hello, " + name + "!"; - } - - // Define a function with multiple parameters - function CalculateArea(width: number, height: number): number { - return width * height; - } - - // Use the functions - induce greeting: string = Greet("Alice"); - induce area: number = CalculateArea(10, 5); - - Observe(greeting); - Observe("Area: " + area); -} Relax -``` - -### 3. Use Control Structures - -```hypno -Focus { - induce score: number = 85; - - // If-else statements - if (score >= 90) { - Observe("Excellent!"); - } else if (score >= 80) { - Observe("Good job!"); - } else if (score >= 70) { - Observe("Not bad!"); - } else { - Observe("Keep trying!"); - } - - // Loops - induce numbers: number[] = [1, 2, 3, 4, 5]; - - for (induce i: number = 0; i < Length(numbers); i = i + 1) { - Observe("Number " + (i + 1) + ": " + numbers[i]); - } - - // While loop - induce count: number = 0; - while (count < 3) { - Observe("Count: " + count); - count = count + 1; - } -} Relax -``` - -## CLI Commands - -HypnoScript CLI provides several useful commands: - -```bash -# Run a script -hyp run script.hyp - -# Check script for errors (linting) -hyp lint script.hyp - -# Measure script performance -hyp benchmark script.hyp - -# Generate documentation -hyp docs script.hyp - -# Show help -hyp --help - -# Show version -hyp --version -``` - -## Troubleshooting - -### Common Issues - -1. **"Command not found" error**: - - - Ensure HypnoScript is properly installed - - Check that the installation directory is in your PATH - - Try restarting your terminal - -2. **Script won't run**: - - - Check for syntax errors using `hyp lint script.hyp` - - Ensure the file has a `.hyp` extension - - Verify the script has proper `Focus { } Relax` structure - -3. **Permission denied**: - - On Linux/macOS, ensure the script file is executable - - Check file permissions: `chmod +x script.hyp` - -### Getting Help - -- **Documentation**: Visit the [HypnoScript Documentation](https://hypnoscript.dev) -- **GitHub Issues**: Report bugs at [GitHub Issues](https://github.com/Kink-Development-Group/hyp-runtime/issues) -- **Community**: Join discussions on [GitHub Discussions](https://github.com/Kink-Development-Group/hyp-runtime/discussions) - -## What's Next? - -Now that you've completed the quick start guide, you can: - -1. **Read the Language Reference** - Learn about all HypnoScript features -2. **Explore Examples** - See practical examples and use cases -3. **Try Advanced Features** - Learn about sessions, tranceify, and more -4. **Build Your Own Projects** - Start creating your own HypnoScript applications - -Welcome to the HypnoScript community! 🚀 diff --git a/HypnoScript.Dokumentation/docs/intro.md b/HypnoScript.Dokumentation/docs/intro.md deleted file mode 100644 index 107d4bd..0000000 --- a/HypnoScript.Dokumentation/docs/intro.md +++ /dev/null @@ -1,98 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Willkommen bei HypnoScript - -HypnoScript ist eine innovative Programmiersprache, die hypnotische Konzepte mit moderner Softwareentwicklung verbindet. Sie bietet eine einzigartige Syntax, die sowohl für Anfänger als auch für erfahrene Entwickler zugänglich ist. - -## Was ist HypnoScript? - -HypnoScript ist eine interpretierte Programmiersprache, die in C# entwickelt wurde und folgende Hauptmerkmale bietet: - -- **Hypnotische Syntax**: Verwendet hypnotische Begriffe wie `Focus`, `Trance`, `Induce`, `Observe` -- **Umfangreiche Standardbibliothek**: Über 200+ Builtin-Funktionen für alle Anwendungsfälle -- **Moderne Features**: Arrays, Records, Funktionen, Sessions, Assertions -- **Runtime-Ready**: CLI-Tools, Test-Framework, Debugging-Unterstützung -- **Plattformübergreifend**: Läuft auf Windows, macOS und Linux - -## Schnellstart - -```hyp -Focus { - entrance { - observe "Willkommen bei HypnoScript!"; - } - - induce name = "Welt"; - observe "Hallo, " + name + "!"; - - induce numbers = [1, 2, 3, 4, 5]; - induce sum = SumArray(numbers); - observe "Summe: " + sum; -} Relax; -``` - -## Hauptfunktionen - -### 🧠 Hypnotische Syntax - -Verwende hypnotische Konzepte für eine intuitive Programmierung: - -- `Focus` - Hauptblock für Programmausführung -- `Trance` - Funktionsdefinitionen -- `Induce` - Variablenzuweisung -- `Observe` - Ausgabe -- `Relax` - Programmende - -### 📚 Umfangreiche Bibliothek - -HypnoScript bietet eine umfassende Standardbibliothek mit über 200 Funktionen: - -- **Array-Funktionen**: `ArrayGet`, `ArraySet`, `ArraySort`, `ShuffleArray` -- **String-Funktionen**: `Length`, `Substring`, `Reverse`, `IsPalindrome` -- **Mathematische Funktionen**: `Sin`, `Cos`, `Sqrt`, `Factorial` -- **System-Funktionen**: `FileExists`, `HttpGet`, `GetCurrentTime` -- **Hypnotische Funktionen**: `DeepTrance`, `HypnoticCountdown`, `TranceInduction` - -### 🛠️ Moderne Entwicklungstools - -- **CLI-Interface**: Vollständige Kommandozeilen-Schnittstelle -- **Test-Framework**: Automatisierte Tests mit Assertions -- **Debugging**: Umfassende Debugging-Unterstützung -- **Runtime-Features**: Webserver, API, Dokumentation - -## Installation - -```bash -# Repository klonen -git clone https://github.com/Kink-Development-Group/hyp-runtime.git -cd hyp-runtime - -# Projekt bauen -dotnet build - -# CLI verwenden -dotnet run --project HypnoScript.CLI -- run example.hyp -``` - -## Nächste Schritte - -- [Installation und Setup](./getting-started/installation) -- [Schnellstart-Guide](./getting-started/quick-start) -- [Sprachreferenz](./language-reference/syntax) -- [Builtin-Funktionen](./builtins/overview) - -## Community - -- **GitHub**: [Kink-Development-Group/hyp-runtime](https://github.com/Kink-Development-Group/hyp-runtime) -- **Issues**: [GitHub Issues](https://github.com/Kink-Development-Group/hyp-runtime/issues) -- **Discussions**: [GitHub Discussions](https://github.com/Kink-Development-Group/hyp-runtime/discussions) - -## Lizenz - -HypnoScript ist unter der MIT-Lizenz veröffentlicht. Siehe [LICENSE](https://github.com/Kink-Development-Group/hyp-runtime/blob/main/LICENSE) für Details. - ---- - -**Bereit, in die hypnotische Welt der Programmierung einzutauchen?** 🧠✨ diff --git a/HypnoScript.Dokumentation/docs/language-reference/operators.md b/HypnoScript.Dokumentation/docs/language-reference/operators.md deleted file mode 100644 index 4bec826..0000000 --- a/HypnoScript.Dokumentation/docs/language-reference/operators.md +++ /dev/null @@ -1,80 +0,0 @@ ---- -sidebar_position: 3 ---- - -# Operatoren - -HypnoScript unterstützt arithmetische, Vergleichs- und logische Operatoren sowie spezielle Operatoren für Arrays und Records. - -## Arithmetische Operatoren - -```bash -| Operator | Bedeutung | Beispiel | Ergebnis | -| -------- | -------------- | -------- | -------- | -| + | Addition | 2 + 3 | 5 | -| - | Subtraktion | 5 - 2 | 3 | -| \* | Multiplikation | 4 \* 2 | 8 | -| / | Division | 8 / 2 | 4 | -| % | Modulo | 7 % 3 | 1 | -| ^ | Potenz | 2 ^ 3 | 8 | -``` - -## Vergleichsoperatoren - -```bash -| Operator | Bedeutung | Beispiel | Ergebnis | -| -------- | -------------- | -------- | -------- | -| == | Gleich | 3 == 3 | true | -| != | Ungleich | 3 != 4 | true | -| < | Kleiner | 2 < 5 | true | -| > | Größer | 5 > 2 | true | -| <= | Kleiner gleich | 2 <= 2 | true | -| >= | Größer gleich | 3 >= 2 | true | -``` - -## Logische Operatoren - -```bash -| Operator | Bedeutung | Beispiel | Ergebnis | -| -------- | ------------- | ------------- | -------- | ---- | --- | ----- | ---- | -| && | Und | true && false | false | -| | | | Oder | true | | false | true | -| ! | Nicht | !true | false | -| ^ | Exklusiv-Oder | true ^ false | true | -``` - -## Array- und Record-Operatoren - -- Zugriff auf Array-Element: `arr[0]` -- Zugriff auf Record-Feld: `person.name` -- Zuweisung: `arr[1] = 42;`, `person.age = 31;` - -## Zuweisungsoperatoren - -```hyp -induce x = 5; -x = x + 1; // 6 -x += 2; // 8 -x -= 3; // 5 -x *= 2; // 10 -x /= 5; // 2 -``` - -## Beispiele - -```hyp -Focus { - entrance { - induce a = 10; - induce b = 3; - observe "a + b = " + (a + b); - observe "a ^ b = " + (a ^ b); - observe "a == b: " + (a == b); - observe "a > b: " + (a > b); - induce arr = [1,2,3]; - observe arr[1]; // 2 - induce person = { name: "Max", age: 30 }; - observe person.name; - } -} Relax; -``` diff --git a/HypnoScript.Dokumentation/docs/language-reference/sessions.md b/HypnoScript.Dokumentation/docs/language-reference/sessions.md deleted file mode 100644 index 16e4ad6..0000000 --- a/HypnoScript.Dokumentation/docs/language-reference/sessions.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Sessions ---- - -# Sessions - -This page will document the sessions feature in HypnoScript. Content coming soon. diff --git a/HypnoScript.Dokumentation/docusaurus.config.js b/HypnoScript.Dokumentation/docusaurus.config.js deleted file mode 100644 index 12070a5..0000000 --- a/HypnoScript.Dokumentation/docusaurus.config.js +++ /dev/null @@ -1,179 +0,0 @@ -// @ts-check -// Note: type annotations allow type checking and IDEs autocompletion - -const lightCodeTheme = require('prism-react-renderer/themes/github'); -const darkCodeTheme = require('prism-react-renderer/themes/dracula'); - -/** @type {import('@docusaurus/types').Config} */ -const config = { - title: 'HypnoScript', - tagline: 'Die hypnotische Programmiersprache', - favicon: 'img/favicon.ico', - - // Set the production url of your site here - url: 'https://Kink-Development-Group.github.io', - // Set the // pathname under which your site is served - // For GitHub pages deployment, it is often '//' - baseUrl: '/hyp-runtime/', - - // GitHub pages deployment config. - // If you aren't using GitHub pages, you don't need these. - organizationName: 'Kink-Development-Group', // Usually your GitHub org/user name. - projectName: 'hyp-runtime', // Usually your repo name. - - onBrokenLinks: 'throw', - onBrokenMarkdownLinks: 'warn', - - // Even if you don't use internalization, you can use this field to set useful - // metadata like html lang. For example, if your site is Chinese, you may want - // to replace "en" with "zh-Hans". - i18n: { - defaultLocale: 'de', - locales: ['de', 'en'], - }, - - presets: [ - [ - 'classic', - /** @type {import('@docusaurus/preset-classic').Options} */ - ({ - docs: { - sidebarPath: require.resolve('./sidebars.js'), - // Please change this to your repo. - // Remove this to remove the "edit this page" links. - editUrl: - 'https://github.com/Kink-Development-Group/hyp-runtime/tree/main/HypnoScript.Dokumentation/', - }, - blog: { - showReadingTime: true, - // Please change this to your repo. - // Remove this to remove the "edit this page" links. - editUrl: - 'https://github.com/Kink-Development-Group/hyp-runtime/tree/main/HypnoScript.Dokumentation/', - }, - theme: { - customCss: require.resolve('./src/css/custom.css'), - }, - }), - ], - ], - - themeConfig: - /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ - ({ - // Replace with your project's social card - image: 'img/hypnoscript-social-card.jpg', - navbar: { - title: 'HypnoScript', - logo: { - alt: 'HypnoScript Logo', - src: 'img/logo.svg', - }, - items: [ - { - type: 'docSidebar', - sidebarId: 'tutorialSidebar', - position: 'left', - label: 'Dokumentation', - }, - { to: '/blog', label: 'Blog', position: 'left' }, - { - href: 'https://github.com/Kink-Development-Group/hyp-runtime', - label: 'GitHub', - position: 'right', - }, - { - type: 'localeDropdown', - position: 'right', - }, - ], - }, - footer: { - style: 'dark', - links: [ - { - title: 'Dokumentation', - items: [ - { - label: 'Erste Schritte', - to: '/docs/intro', - }, - { - label: 'Sprachreferenz', - to: '/docs/category/sprachreferenz', - }, - { - label: 'Builtin-Funktionen', - to: '/docs/category/builtin-funktionen', - }, - ], - }, - { - title: 'Community', - items: [ - { - label: 'GitHub', - href: 'https://github.com/Kink-Development-Group/hyp-runtime', - }, - { - label: 'Issues', - href: 'https://github.com/Kink-Development-Group/hyp-runtime/issues', - }, - { - label: 'Discussions', - href: 'https://github.com/Kink-Development-Group/hyp-runtime/discussions', - }, - ], - }, - { - title: 'Mehr', - items: [ - { - label: 'Blog', - to: '/blog', - }, - { - label: 'Changelog', - to: '/docs/changelog', - }, - ], - }, - ], - copyright: `Copyright © ${new Date().getFullYear()} HypnoScript. Built with Docusaurus.`, - }, - prism: { - theme: lightCodeTheme, - darkTheme: darkCodeTheme, - additionalLanguages: ['csharp', 'powershell', 'bash'], - }, - algolia: { - // The application ID provided by Algolia - appId: 'YOUR_APP_ID', - - // Public API key: it is safe to commit it - apiKey: 'YOUR_SEARCH_API_KEY', - - indexName: 'hypnoscript', - - // Optional: see doc section below - contextualSearch: true, - - // Optional: Specify domains where the navigation should occur through window.location instead on history.push. Useful when our Algolia config crawls multiple documentation sites and we want to navigate with window.location.href to them. - externalUrlRegex: 'external\\.com|domain\\.com', - - // Optional: Replace parts of the item URLs from Algolia search. Useful when using the same search index for multiple deployments using a different baseUrl. You can use regexp or string in the `from` param. For example: localhost:3000 vs myCompany.com/docs - replaceSearchResultPathname: { - from: '/docs/', // or as RegExp: /\/docs\// - to: '/', - }, - - // Optional: Algolia search parameters - searchParameters: {}, - - // Optional: path for search page that enabled by default (`false` to disable it) - searchPagePath: 'search', - }, - }), -}; - -module.exports = config; diff --git a/HypnoScript.Dokumentation/docusaurus.config.ts b/HypnoScript.Dokumentation/docusaurus.config.ts deleted file mode 100644 index 53aef0d..0000000 --- a/HypnoScript.Dokumentation/docusaurus.config.ts +++ /dev/null @@ -1,148 +0,0 @@ -import type * as Preset from '@docusaurus/preset-classic'; -import type { Config } from '@docusaurus/types'; -import { themes as prismThemes } from 'prism-react-renderer'; - -// This runs in Node.js - Don't use client-side code here (browser APIs, JSX...) - -const config: Config = { - title: 'HypnoScript', - tagline: 'Code with style', - favicon: 'img/favicon.ico', - - // Future flags, see https://docusaurus.io/docs/api/docusaurus-config#future - future: { - v4: true, // Improve compatibility with the upcoming Docusaurus v4 - }, - - // Set the production url of your site here - url: 'https://Kink-Development-Group.github.io', - // Set the // pathname under which your site is served - // For GitHub pages deployment, it is often '//' - baseUrl: '/hyp-runtime/', - - // GitHub pages deployment config. - // If you aren't using GitHub pages, you don't need these. - organizationName: 'Kink-Development-Group', // Usually your GitHub org/user name. - projectName: 'hyp-runtime', // Usually your repo name. - - onBrokenLinks: 'throw', - onBrokenMarkdownLinks: 'warn', - - // Even if you don't use internationalization, you can use this field to set - // useful metadata like html lang. For example, if your site is Chinese, you - // may want to replace "en" with "zh-Hans". - i18n: { - defaultLocale: 'en', - locales: ['en'], - }, - - presets: [ - [ - 'classic', - { - docs: { - sidebarPath: './sidebars.ts', - // Please change this to your repo. - // Remove this to remove the "edit this page" links. - editUrl: - 'https://github.com/Kink-Development-Group/hyp-runtime/tree/main/HypnoScript.Dokumentation/', - }, - blog: { - showReadingTime: true, - feedOptions: { - type: ['rss', 'atom'], - xslt: true, - }, - // Please change this to your repo. - // Remove this to remove the "edit this page" links. - editUrl: - 'https://github.com/Kink-Development-Group/hyp-runtime/tree/main/HypnoScript.Dokumentation/', - // Useful options to enforce blogging best practices - onInlineTags: 'warn', - onInlineAuthors: 'warn', - onUntruncatedBlogPosts: 'warn', - }, - theme: { - customCss: './src/css/custom.css', - }, - } satisfies Preset.Options, - ], - ], - - themeConfig: { - // Replace with your project's social card - image: 'img/docusaurus-social-card.jpg', - navbar: { - title: 'HYPNO Script', - logo: { - alt: 'HYP Logo', - src: 'img/logo.svg', - }, - items: [ - { - type: 'docSidebar', - sidebarId: 'tutorialSidebar', - position: 'left', - label: 'Tutorial', - }, - { to: '/blog', label: 'Blog', position: 'left' }, - { - href: 'https://github.com/Kink-Development-Group/hyp-runtime', - label: 'GitHub', - position: 'right', - }, - ], - }, - footer: { - style: 'dark', - links: [ - { - title: 'Docs', - items: [ - { - label: 'Tutorial', - to: '/docs/intro', - }, - ], - }, - { - title: 'Community', - items: [ - { - label: 'Stack Overflow', - href: 'https://stackoverflow.com/questions/tagged/docusaurus', - }, - { - label: 'Discord', - href: 'https://discordapp.com/invite/docusaurus', - }, - { - label: 'X', - href: 'https://x.com/docusaurus', - }, - ], - }, - { - title: 'More', - items: [ - { - label: 'Blog', - to: '/blog', - }, - { - label: 'GitHub', - href: 'https://github.com/Kink-Development-Group/hyp-runtime', - }, - ], - }, - ], - copyright: `Copyright © ${new Date().getFullYear()} HypnoScript. Built with Docusaurus.`, - }, - prism: { - theme: prismThemes.github, - darkTheme: prismThemes.dracula, - }, - } satisfies Preset.ThemeConfig, -}; - -export default config; diff --git a/HypnoScript.Dokumentation/package-lock.json b/HypnoScript.Dokumentation/package-lock.json deleted file mode 100644 index 13d3971..0000000 --- a/HypnoScript.Dokumentation/package-lock.json +++ /dev/null @@ -1,17464 +0,0 @@ -{ - "name": "hypnoscript-documentation", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "hypnoscript-documentation", - "version": "1.0.0", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "^3.8.1", - "@docusaurus/preset-classic": "^3.8.1", - "@docusaurus/theme-search-algolia": "^3.8.1", - "@mdx-js/react": "^3.0.0", - "clsx": "^2.1.0", - "prism-react-renderer": "^2.3.1", - "react": "^18.2.0", - "react-dom": "^18.2.0" - }, - "devDependencies": { - "@docusaurus/module-type-aliases": "^3.8.1", - "@docusaurus/tsconfig": "^3.8.1", - "@docusaurus/types": "^3.8.1", - "typescript": "^5.3.3" - }, - "engines": { - "node": ">=18.0" - } - }, - "node_modules/@algolia/autocomplete-core": { - "version": "1.17.9", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.17.9.tgz", - "integrity": "sha512-O7BxrpLDPJWWHv/DLA9DRFWs+iY1uOJZkqUwjS5HSZAGcl0hIVCQ97LTLewiZmZ402JYUrun+8NqFP+hCknlbQ==", - "license": "MIT", - "dependencies": { - "@algolia/autocomplete-plugin-algolia-insights": "1.17.9", - "@algolia/autocomplete-shared": "1.17.9" - } - }, - "node_modules/@algolia/autocomplete-plugin-algolia-insights": { - "version": "1.17.9", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.17.9.tgz", - "integrity": "sha512-u1fEHkCbWF92DBeB/KHeMacsjsoI0wFhjZtlCq2ddZbAehshbZST6Hs0Avkc0s+4UyBGbMDnSuXHLuvRWK5iDQ==", - "license": "MIT", - "dependencies": { - "@algolia/autocomplete-shared": "1.17.9" - }, - "peerDependencies": { - "search-insights": ">= 1 < 3" - } - }, - "node_modules/@algolia/autocomplete-preset-algolia": { - "version": "1.17.9", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.17.9.tgz", - "integrity": "sha512-Na1OuceSJeg8j7ZWn5ssMu/Ax3amtOwk76u4h5J4eK2Nx2KB5qt0Z4cOapCsxot9VcEN11ADV5aUSlQF4RhGjQ==", - "license": "MIT", - "dependencies": { - "@algolia/autocomplete-shared": "1.17.9" - }, - "peerDependencies": { - "@algolia/client-search": ">= 4.9.1 < 6", - "algoliasearch": ">= 4.9.1 < 6" - } - }, - "node_modules/@algolia/autocomplete-shared": { - "version": "1.17.9", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.17.9.tgz", - "integrity": "sha512-iDf05JDQ7I0b7JEA/9IektxN/80a2MZ1ToohfmNS3rfeuQnIKI3IJlIafD0xu4StbtQTghx9T3Maa97ytkXenQ==", - "license": "MIT", - "peerDependencies": { - "@algolia/client-search": ">= 4.9.1 < 6", - "algoliasearch": ">= 4.9.1 < 6" - } - }, - "node_modules/@algolia/client-abtesting": { - "version": "5.29.0", - "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.29.0.tgz", - "integrity": "sha512-AM/6LYMSTnZvAT5IarLEKjYWOdV+Fb+LVs8JRq88jn8HH6bpVUtjWdOZXqX1hJRXuCAY8SdQfb7F8uEiMNXdYQ==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.29.0", - "@algolia/requester-browser-xhr": "5.29.0", - "@algolia/requester-fetch": "5.29.0", - "@algolia/requester-node-http": "5.29.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/client-analytics": { - "version": "5.29.0", - "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.29.0.tgz", - "integrity": "sha512-La34HJh90l0waw3wl5zETO8TuukeUyjcXhmjYZL3CAPLggmKv74mobiGRIb+mmBENybiFDXf/BeKFLhuDYWMMQ==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.29.0", - "@algolia/requester-browser-xhr": "5.29.0", - "@algolia/requester-fetch": "5.29.0", - "@algolia/requester-node-http": "5.29.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/client-common": { - "version": "5.29.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.29.0.tgz", - "integrity": "sha512-T0lzJH/JiCxQYtCcnWy7Jf1w/qjGDXTi2npyF9B9UsTvXB97GRC6icyfXxe21mhYvhQcaB1EQ/J2575FXxi2rA==", - "license": "MIT", - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/client-insights": { - "version": "5.29.0", - "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.29.0.tgz", - "integrity": "sha512-A39F1zmHY9aev0z4Rt3fTLcGN5AG1VsVUkVWy6yQG5BRDScktH+U5m3zXwThwniBTDV1HrPgiGHZeWb67GkR2Q==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.29.0", - "@algolia/requester-browser-xhr": "5.29.0", - "@algolia/requester-fetch": "5.29.0", - "@algolia/requester-node-http": "5.29.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/client-personalization": { - "version": "5.29.0", - "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.29.0.tgz", - "integrity": "sha512-ibxmh2wKKrzu5du02gp8CLpRMeo+b/75e4ORct98CT7mIxuYFXowULwCd6cMMkz/R0LpKXIbTUl15UL5soaiUQ==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.29.0", - "@algolia/requester-browser-xhr": "5.29.0", - "@algolia/requester-fetch": "5.29.0", - "@algolia/requester-node-http": "5.29.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/client-query-suggestions": { - "version": "5.29.0", - "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.29.0.tgz", - "integrity": "sha512-VZq4/AukOoJC2WSwF6J5sBtt+kImOoBwQc1nH3tgI+cxJBg7B77UsNC+jT6eP2dQCwGKBBRTmtPLUTDDnHpMgA==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.29.0", - "@algolia/requester-browser-xhr": "5.29.0", - "@algolia/requester-fetch": "5.29.0", - "@algolia/requester-node-http": "5.29.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/client-search": { - "version": "5.29.0", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.29.0.tgz", - "integrity": "sha512-cZ0Iq3OzFUPpgszzDr1G1aJV5UMIZ4VygJ2Az252q4Rdf5cQMhYEIKArWY/oUjMhQmosM8ygOovNq7gvA9CdCg==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.29.0", - "@algolia/requester-browser-xhr": "5.29.0", - "@algolia/requester-fetch": "5.29.0", - "@algolia/requester-node-http": "5.29.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/events": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@algolia/events/-/events-4.0.1.tgz", - "integrity": "sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ==", - "license": "MIT" - }, - "node_modules/@algolia/ingestion": { - "version": "1.29.0", - "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.29.0.tgz", - "integrity": "sha512-scBXn0wO5tZCxmO6evfa7A3bGryfyOI3aoXqSQBj5SRvNYXaUlFWQ/iKI70gRe/82ICwE0ICXbHT/wIvxOW7vw==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.29.0", - "@algolia/requester-browser-xhr": "5.29.0", - "@algolia/requester-fetch": "5.29.0", - "@algolia/requester-node-http": "5.29.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/monitoring": { - "version": "1.29.0", - "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.29.0.tgz", - "integrity": "sha512-FGWWG9jLFhsKB7YiDjM2dwQOYnWu//7Oxrb2vT96N7+s+hg1mdHHfHNRyEudWdxd4jkMhBjeqNA21VbTiOIPVg==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.29.0", - "@algolia/requester-browser-xhr": "5.29.0", - "@algolia/requester-fetch": "5.29.0", - "@algolia/requester-node-http": "5.29.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/recommend": { - "version": "5.29.0", - "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.29.0.tgz", - "integrity": "sha512-xte5+mpdfEARAu61KXa4ewpjchoZuJlAlvQb8ptK6hgHlBHDnYooy1bmOFpokaAICrq/H9HpoqNUX71n+3249A==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.29.0", - "@algolia/requester-browser-xhr": "5.29.0", - "@algolia/requester-fetch": "5.29.0", - "@algolia/requester-node-http": "5.29.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/requester-browser-xhr": { - "version": "5.29.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.29.0.tgz", - "integrity": "sha512-og+7Em75aPHhahEUScq2HQ3J7ULN63Levtd87BYMpn6Im5d5cNhaC4QAUsXu6LWqxRPgh4G+i+wIb6tVhDhg2A==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.29.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/requester-fetch": { - "version": "5.29.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.29.0.tgz", - "integrity": "sha512-JCxapz7neAy8hT/nQpCvOrI5JO8VyQ1kPvBiaXWNC1prVq0UMYHEL52o1BsPvtXfdQ7BVq19OIq6TjOI06mV/w==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.29.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/requester-node-http": { - "version": "5.29.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.29.0.tgz", - "integrity": "sha512-lVBD81RBW5VTdEYgnzCz7Pf9j2H44aymCP+/eHGJu4vhU+1O8aKf3TVBgbQr5UM6xoe8IkR/B112XY6YIG2vtg==", - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.29.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "license": "Apache-2.0", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.27.1", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.27.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.27.5.tgz", - "integrity": "sha512-KiRAp/VoJaWkkte84TvUd9qjdbZAdiqyvMxrGl1N6vzFogKmaLgoM3L1kgtLicp2HP5fBJS8JrZKLVIZGVJAVg==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.27.4", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.27.4.tgz", - "integrity": "sha512-bXYxrXFubeYdvB0NhD/NBB3Qi6aZeV20GOWVI47t2dkecCEoneR4NPVcb7abpXDEvejgrUfFtG6vG/zxAKmg+g==", - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.27.3", - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-module-transforms": "^7.27.3", - "@babel/helpers": "^7.27.4", - "@babel/parser": "^7.27.4", - "@babel/template": "^7.27.2", - "@babel/traverse": "^7.27.4", - "@babel/types": "^7.27.3", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/generator": { - "version": "7.27.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.5.tgz", - "integrity": "sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw==", - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.27.5", - "@babel/types": "^7.27.3", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^3.0.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.27.3", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", - "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.27.3" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", - "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.27.2", - "@babel/helper-validator-option": "^7.27.1", - "browserslist": "^4.24.0", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.27.1.tgz", - "integrity": "sha512-QwGAmuvM17btKU5VqXfb+Giw4JcN0hjuufz3DYnpeVDvZLAObloM77bhMXiqry3Iio+Ai4phVRDwl6WU10+r5A==", - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "@babel/helper-member-expression-to-functions": "^7.27.1", - "@babel/helper-optimise-call-expression": "^7.27.1", - "@babel/helper-replace-supers": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", - "@babel/traverse": "^7.27.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.27.1.tgz", - "integrity": "sha512-uVDC72XVf8UbrH5qQTc18Agb8emwjTiZrQE11Nv3CuBEZmVvTwwE9CBUEvHku06gQCAyYf8Nv6ja1IN+6LMbxQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "regexpu-core": "^6.2.0", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.4.tgz", - "integrity": "sha512-jljfR1rGnXXNWnmQg2K3+bvhkxB51Rl32QRaOTuwwjviGrHzIbSc8+x9CpraDtbT7mfyjXObULP4w/adunNwAw==", - "license": "MIT", - "dependencies": { - "@babel/helper-compilation-targets": "^7.22.6", - "@babel/helper-plugin-utils": "^7.22.5", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.27.1.tgz", - "integrity": "sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==", - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", - "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.27.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz", - "integrity": "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==", - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1", - "@babel/traverse": "^7.27.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", - "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", - "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz", - "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==", - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "@babel/helper-wrap-function": "^7.27.1", - "@babel/traverse": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz", - "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==", - "license": "MIT", - "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.27.1", - "@babel/helper-optimise-call-expression": "^7.27.1", - "@babel/traverse": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", - "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", - "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", - "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-wrap-function": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.27.1.tgz", - "integrity": "sha512-NFJK2sHUvrjo8wAU/nQTWU890/zB2jj0qBcCbZbbf+005cAsv6tMjXz31fBign6M5ov1o0Bllu+9nbqkfsjjJQ==", - "license": "MIT", - "dependencies": { - "@babel/template": "^7.27.1", - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.27.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.6.tgz", - "integrity": "sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==", - "license": "MIT", - "dependencies": { - "@babel/template": "^7.27.2", - "@babel/types": "^7.27.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.27.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.5.tgz", - "integrity": "sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.27.3" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.27.1.tgz", - "integrity": "sha512-QPG3C9cCVRQLxAVwmefEmwdTanECuUBMQZ/ym5kiw3XKCGA7qkuQLcjWWHcrD/GKbn/WmJwaezfuuAOcyKlRPA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/traverse": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.27.1.tgz", - "integrity": "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.27.1.tgz", - "integrity": "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz", - "integrity": "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", - "@babel/plugin-transform-optional-chaining": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.13.0" - } - }, - "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.27.1.tgz", - "integrity": "sha512-6BpaYGDavZqkI6yT+KSPdpZFfpnd68UKXbcjI9pJ13pvHhPrCKWOOLp+ysvMeA+DxnhuPpgIaRpxRxo5A9t5jw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/traverse": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.21.0-placeholder-for-preset-env.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", - "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.27.1.tgz", - "integrity": "sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz", - "integrity": "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz", - "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz", - "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-unicode-sets-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", - "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz", - "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.27.1.tgz", - "integrity": "sha512-eST9RrwlpaoJBDHShc+DS2SG4ATTi2MYNb4OxYkf3n+7eb49LWpnS+HSpVfW4x927qQwgk8A2hGNVaajAEw0EA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-remap-async-to-generator": "^7.27.1", - "@babel/traverse": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.27.1.tgz", - "integrity": "sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA==", - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-remap-async-to-generator": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz", - "integrity": "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.27.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.27.5.tgz", - "integrity": "sha512-JF6uE2s67f0y2RZcm2kpAUEbD50vH62TyWVebxwHAlbSdM49VqPz8t4a1uIjp4NIOIZ4xzLfjY5emt/RCyC7TQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.27.1.tgz", - "integrity": "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==", - "license": "MIT", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.27.1.tgz", - "integrity": "sha512-s734HmYU78MVzZ++joYM+NkJusItbdRcbm+AGRgJCt3iA+yux0QpD9cBVdz3tKyrjVYWRl7j0mHSmv4lhV0aoA==", - "license": "MIT", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0" - } - }, - "node_modules/@babel/plugin-transform-classes": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.27.1.tgz", - "integrity": "sha512-7iLhfFAubmpeJe/Wo2TVuDrykh/zlWXLzPNdL0Jqn/Xu8R3QQ8h9ff8FQoISZOsw74/HFqFI7NX63HN7QFIHKA==", - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "@babel/helper-compilation-targets": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-replace-supers": "^7.27.1", - "@babel/traverse": "^7.27.1", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.27.1.tgz", - "integrity": "sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/template": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.27.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.27.3.tgz", - "integrity": "sha512-s4Jrok82JpiaIprtY2nHsYmrThKvvwgHwjgd7UMiYhZaN0asdXNLr0y+NjTfkA7SyQE5i2Fb7eawUOZmLvyqOA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.27.1.tgz", - "integrity": "sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw==", - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz", - "integrity": "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.27.1.tgz", - "integrity": "sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.27.1.tgz", - "integrity": "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.27.1.tgz", - "integrity": "sha512-uspvXnhHvGKf2r4VVtBpeFnuDWsJLQ6MF6lGJLC89jBR1uoVeqM416AZtTuhTezOfgHicpJQmoD5YUakO/YmXQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz", - "integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-for-of": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz", - "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-function-name": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz", - "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-compilation-targets": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/traverse": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.27.1.tgz", - "integrity": "sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-literals": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz", - "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.27.1.tgz", - "integrity": "sha512-SJvDs5dXxiae4FbSL1aBJlG4wvl594N6YEVVn9e3JGulwioy6z3oPjx/sQBO3Y4NwUu5HNix6KJ3wBZoewcdbw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz", - "integrity": "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz", - "integrity": "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==", - "license": "MIT", - "dependencies": { - "@babel/helper-module-transforms": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz", - "integrity": "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==", - "license": "MIT", - "dependencies": { - "@babel/helper-module-transforms": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.27.1.tgz", - "integrity": "sha512-w5N1XzsRbc0PQStASMksmUeqECuzKuTJer7kFagK8AXgpCMkeDMO5S+aaFb7A51ZYDF7XI34qsTX+fkHiIm5yA==", - "license": "MIT", - "dependencies": { - "@babel/helper-module-transforms": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1", - "@babel/traverse": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz", - "integrity": "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==", - "license": "MIT", - "dependencies": { - "@babel/helper-module-transforms": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.27.1.tgz", - "integrity": "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==", - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-new-target": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz", - "integrity": "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.27.1.tgz", - "integrity": "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.27.1.tgz", - "integrity": "sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.27.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.27.3.tgz", - "integrity": "sha512-7ZZtznF9g4l2JCImCo5LNKFHB5eXnN39lLtLY5Tg+VkR0jwOt7TBciMckuiQIOIW7L5tkQOCh3bVGYeXgMx52Q==", - "license": "MIT", - "dependencies": { - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/plugin-transform-destructuring": "^7.27.3", - "@babel/plugin-transform-parameters": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-object-super": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz", - "integrity": "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-replace-supers": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.27.1.tgz", - "integrity": "sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.27.1.tgz", - "integrity": "sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-parameters": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.1.tgz", - "integrity": "sha512-018KRk76HWKeZ5l4oTj2zPpSh+NbGdt0st5S6x0pga6HgrjBOJb24mMDHorFopOOd6YHkLgOZ+zaCjZGPO4aKg==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.27.1.tgz", - "integrity": "sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA==", - "license": "MIT", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.27.1.tgz", - "integrity": "sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "@babel/helper-create-class-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz", - "integrity": "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-constant-elements": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.27.1.tgz", - "integrity": "sha512-edoidOjl/ZxvYo4lSBOQGDSyToYVkTAwyVoa2tkuYTSmjrB1+uAedoL5iROVLXkxH+vRgA7uP4tMg2pUJpZ3Ug==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-display-name": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.27.1.tgz", - "integrity": "sha512-p9+Vl3yuHPmkirRrg021XiP+EETmPMQTLr6Ayjj85RLNEbb3Eya/4VI0vAdzQG9SEAl2Lnt7fy5lZyMzjYoZQQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.27.1.tgz", - "integrity": "sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw==", - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/plugin-syntax-jsx": "^7.27.1", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx-development": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.27.1.tgz", - "integrity": "sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q==", - "license": "MIT", - "dependencies": { - "@babel/plugin-transform-react-jsx": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-pure-annotations": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.27.1.tgz", - "integrity": "sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA==", - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.27.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.27.5.tgz", - "integrity": "sha512-uhB8yHerfe3MWnuLAhEbeQ4afVoqv8BQsPqrTv7e/jZ9y00kJL6l9a/f4OWaKxotmjzewfEyXE1vgDJenkQ2/Q==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-regexp-modifiers": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.27.1.tgz", - "integrity": "sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA==", - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz", - "integrity": "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-runtime": { - "version": "7.27.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.27.4.tgz", - "integrity": "sha512-D68nR5zxU64EUzV8i7T3R5XP0Xhrou/amNnddsRQssx6GrTLdZl1rLxyjtVZBd+v/NVX4AbTPOB5aU8thAZV1A==", - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "babel-plugin-polyfill-corejs2": "^0.4.10", - "babel-plugin-polyfill-corejs3": "^0.11.0", - "babel-plugin-polyfill-regenerator": "^0.6.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz", - "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-spread": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.27.1.tgz", - "integrity": "sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz", - "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz", - "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz", - "integrity": "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-typescript": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.27.1.tgz", - "integrity": "sha512-Q5sT5+O4QUebHdbwKedFBEwRLb02zJ7r4A5Gg2hUoLuU3FjdMcyqcywqUrLCaDsFCxzokf7u9kuy7qz51YUuAg==", - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "@babel/helper-create-class-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", - "@babel/plugin-syntax-typescript": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz", - "integrity": "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-property-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.27.1.tgz", - "integrity": "sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q==", - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz", - "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==", - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.27.1.tgz", - "integrity": "sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw==", - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/preset-env": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.27.2.tgz", - "integrity": "sha512-Ma4zSuYSlGNRlCLO+EAzLnCmJK2vdstgv+n7aUP+/IKZrOfWHOJVdSJtuub8RzHTj3ahD37k5OKJWvzf16TQyQ==", - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.27.2", - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-validator-option": "^7.27.1", - "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.27.1", - "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.27.1", - "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", - "@babel/plugin-syntax-import-assertions": "^7.27.1", - "@babel/plugin-syntax-import-attributes": "^7.27.1", - "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.27.1", - "@babel/plugin-transform-async-generator-functions": "^7.27.1", - "@babel/plugin-transform-async-to-generator": "^7.27.1", - "@babel/plugin-transform-block-scoped-functions": "^7.27.1", - "@babel/plugin-transform-block-scoping": "^7.27.1", - "@babel/plugin-transform-class-properties": "^7.27.1", - "@babel/plugin-transform-class-static-block": "^7.27.1", - "@babel/plugin-transform-classes": "^7.27.1", - "@babel/plugin-transform-computed-properties": "^7.27.1", - "@babel/plugin-transform-destructuring": "^7.27.1", - "@babel/plugin-transform-dotall-regex": "^7.27.1", - "@babel/plugin-transform-duplicate-keys": "^7.27.1", - "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.27.1", - "@babel/plugin-transform-dynamic-import": "^7.27.1", - "@babel/plugin-transform-exponentiation-operator": "^7.27.1", - "@babel/plugin-transform-export-namespace-from": "^7.27.1", - "@babel/plugin-transform-for-of": "^7.27.1", - "@babel/plugin-transform-function-name": "^7.27.1", - "@babel/plugin-transform-json-strings": "^7.27.1", - "@babel/plugin-transform-literals": "^7.27.1", - "@babel/plugin-transform-logical-assignment-operators": "^7.27.1", - "@babel/plugin-transform-member-expression-literals": "^7.27.1", - "@babel/plugin-transform-modules-amd": "^7.27.1", - "@babel/plugin-transform-modules-commonjs": "^7.27.1", - "@babel/plugin-transform-modules-systemjs": "^7.27.1", - "@babel/plugin-transform-modules-umd": "^7.27.1", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.27.1", - "@babel/plugin-transform-new-target": "^7.27.1", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1", - "@babel/plugin-transform-numeric-separator": "^7.27.1", - "@babel/plugin-transform-object-rest-spread": "^7.27.2", - "@babel/plugin-transform-object-super": "^7.27.1", - "@babel/plugin-transform-optional-catch-binding": "^7.27.1", - "@babel/plugin-transform-optional-chaining": "^7.27.1", - "@babel/plugin-transform-parameters": "^7.27.1", - "@babel/plugin-transform-private-methods": "^7.27.1", - "@babel/plugin-transform-private-property-in-object": "^7.27.1", - "@babel/plugin-transform-property-literals": "^7.27.1", - "@babel/plugin-transform-regenerator": "^7.27.1", - "@babel/plugin-transform-regexp-modifiers": "^7.27.1", - "@babel/plugin-transform-reserved-words": "^7.27.1", - "@babel/plugin-transform-shorthand-properties": "^7.27.1", - "@babel/plugin-transform-spread": "^7.27.1", - "@babel/plugin-transform-sticky-regex": "^7.27.1", - "@babel/plugin-transform-template-literals": "^7.27.1", - "@babel/plugin-transform-typeof-symbol": "^7.27.1", - "@babel/plugin-transform-unicode-escapes": "^7.27.1", - "@babel/plugin-transform-unicode-property-regex": "^7.27.1", - "@babel/plugin-transform-unicode-regex": "^7.27.1", - "@babel/plugin-transform-unicode-sets-regex": "^7.27.1", - "@babel/preset-modules": "0.1.6-no-external-plugins", - "babel-plugin-polyfill-corejs2": "^0.4.10", - "babel-plugin-polyfill-corejs3": "^0.11.0", - "babel-plugin-polyfill-regenerator": "^0.6.1", - "core-js-compat": "^3.40.0", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-env/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/preset-modules": { - "version": "0.1.6-no-external-plugins", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", - "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/@babel/preset-react": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.27.1.tgz", - "integrity": "sha512-oJHWh2gLhU9dW9HHr42q0cI0/iHHXTLGe39qvpAZZzagHy0MzYLCnCVV0symeRvzmjHyVU7mw2K06E6u/JwbhA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-validator-option": "^7.27.1", - "@babel/plugin-transform-react-display-name": "^7.27.1", - "@babel/plugin-transform-react-jsx": "^7.27.1", - "@babel/plugin-transform-react-jsx-development": "^7.27.1", - "@babel/plugin-transform-react-pure-annotations": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-typescript": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.27.1.tgz", - "integrity": "sha512-l7WfQfX0WK4M0v2RudjuQK4u99BS6yLHYEmdtVPP7lKV013zr9DygFuWNlnbvQ9LR+LS0Egz/XAvGx5U9MX0fQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-validator-option": "^7.27.1", - "@babel/plugin-syntax-jsx": "^7.27.1", - "@babel/plugin-transform-modules-commonjs": "^7.27.1", - "@babel/plugin-transform-typescript": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/runtime": { - "version": "7.27.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.6.tgz", - "integrity": "sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/runtime-corejs3": { - "version": "7.27.6", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.27.6.tgz", - "integrity": "sha512-vDVrlmRAY8z9Ul/HxT+8ceAru95LQgkSKiXkSYZvqtbkPSfhZJgpRp45Cldbh1GJ1kxzQkI70AqyrTI58KpaWQ==", - "license": "MIT", - "dependencies": { - "core-js-pure": "^3.30.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/template": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", - "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/parser": "^7.27.2", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.27.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.4.tgz", - "integrity": "sha512-oNcu2QbHqts9BtOWJosOVJapWjBDSxGCpFvikNR5TGDYDQf3JwpIoMzIKrvfoti93cLfPJEG4tH9SPVeyCGgdA==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.27.3", - "@babel/parser": "^7.27.4", - "@babel/template": "^7.27.2", - "@babel/types": "^7.27.3", - "debug": "^4.3.1", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.27.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.6.tgz", - "integrity": "sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q==", - "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/@csstools/cascade-layer-name-parser": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@csstools/cascade-layer-name-parser/-/cascade-layer-name-parser-2.0.5.tgz", - "integrity": "sha512-p1ko5eHgV+MgXFVa4STPKpvPxr6ReS8oS2jzTukjR74i5zJNyWO1ZM1m8YKBXnzDKWfBN1ztLYlHxbVemDD88A==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" - } - }, - "node_modules/@csstools/color-helpers": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.0.2.tgz", - "integrity": "sha512-JqWH1vsgdGcw2RR6VliXXdA0/59LttzlU8UlRT/iUUsEeWfYq8I+K0yhihEUTTHLRm1EXvpsCx3083EU15ecsA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "engines": { - "node": ">=18" - } - }, - "node_modules/@csstools/css-calc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz", - "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" - } - }, - "node_modules/@csstools/css-color-parser": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.0.10.tgz", - "integrity": "sha512-TiJ5Ajr6WRd1r8HSiwJvZBiJOqtH86aHpUjq5aEKWHiII2Qfjqd/HCWKPOW8EP4vcspXbHnXrwIDlu5savQipg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "dependencies": { - "@csstools/color-helpers": "^5.0.2", - "@csstools/css-calc": "^2.1.4" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" - } - }, - "node_modules/@csstools/css-parser-algorithms": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", - "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@csstools/css-tokenizer": "^3.0.4" - } - }, - "node_modules/@csstools/css-tokenizer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", - "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/@csstools/media-query-list-parser": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-4.0.3.tgz", - "integrity": "sha512-HAYH7d3TLRHDOUQK4mZKf9k9Ph/m8Akstg66ywKR4SFAigjs3yBiUeZtFxywiTm5moZMAp/5W/ZuFnNXXYLuuQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" - } - }, - "node_modules/@csstools/postcss-cascade-layers": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-5.0.1.tgz", - "integrity": "sha512-XOfhI7GShVcKiKwmPAnWSqd2tBR0uxt+runAxttbSp/LY2U16yAVPmAf7e9q4JJ0d+xMNmpwNDLBXnmRCl3HMQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/selector-specificity": "^5.0.0", - "postcss-selector-parser": "^7.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-cascade-layers/node_modules/@csstools/selector-specificity": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", - "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss-selector-parser": "^7.0.0" - } - }, - "node_modules/@csstools/postcss-cascade-layers/node_modules/postcss-selector-parser": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", - "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@csstools/postcss-color-function": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function/-/postcss-color-function-4.0.10.tgz", - "integrity": "sha512-4dY0NBu7NVIpzxZRgh/Q/0GPSz/jLSw0i/u3LTUor0BkQcz/fNhN10mSWBDsL0p9nDb0Ky1PD6/dcGbhACuFTQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/css-color-parser": "^3.0.10", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4", - "@csstools/postcss-progressive-custom-properties": "^4.1.0", - "@csstools/utilities": "^2.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-color-mix-function": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/@csstools/postcss-color-mix-function/-/postcss-color-mix-function-3.0.10.tgz", - "integrity": "sha512-P0lIbQW9I4ShE7uBgZRib/lMTf9XMjJkFl/d6w4EMNHu2qvQ6zljJGEcBkw/NsBtq/6q3WrmgxSS8kHtPMkK4Q==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/css-color-parser": "^3.0.10", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4", - "@csstools/postcss-progressive-custom-properties": "^4.1.0", - "@csstools/utilities": "^2.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-color-mix-variadic-function-arguments": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-color-mix-variadic-function-arguments/-/postcss-color-mix-variadic-function-arguments-1.0.0.tgz", - "integrity": "sha512-Z5WhouTyD74dPFPrVE7KydgNS9VvnjB8qcdes9ARpCOItb4jTnm7cHp4FhxCRUoyhabD0WVv43wbkJ4p8hLAlQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/css-color-parser": "^3.0.10", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4", - "@csstools/postcss-progressive-custom-properties": "^4.1.0", - "@csstools/utilities": "^2.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-content-alt-text": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@csstools/postcss-content-alt-text/-/postcss-content-alt-text-2.0.6.tgz", - "integrity": "sha512-eRjLbOjblXq+byyaedQRSrAejKGNAFued+LcbzT+LCL78fabxHkxYjBbxkroONxHHYu2qxhFK2dBStTLPG3jpQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4", - "@csstools/postcss-progressive-custom-properties": "^4.1.0", - "@csstools/utilities": "^2.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-exponential-functions": { - "version": "2.0.9", - "resolved": "https://registry.npmjs.org/@csstools/postcss-exponential-functions/-/postcss-exponential-functions-2.0.9.tgz", - "integrity": "sha512-abg2W/PI3HXwS/CZshSa79kNWNZHdJPMBXeZNyPQFbbj8sKO3jXxOt/wF7juJVjyDTc6JrvaUZYFcSBZBhaxjw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/css-calc": "^2.1.4", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-font-format-keywords": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-4.0.0.tgz", - "integrity": "sha512-usBzw9aCRDvchpok6C+4TXC57btc4bJtmKQWOHQxOVKen1ZfVqBUuCZ/wuqdX5GHsD0NRSr9XTP+5ID1ZZQBXw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/utilities": "^2.0.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-gamut-mapping": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@csstools/postcss-gamut-mapping/-/postcss-gamut-mapping-2.0.10.tgz", - "integrity": "sha512-QDGqhJlvFnDlaPAfCYPsnwVA6ze+8hhrwevYWlnUeSjkkZfBpcCO42SaUD8jiLlq7niouyLgvup5lh+f1qessg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/css-color-parser": "^3.0.10", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-gradients-interpolation-method": { - "version": "5.0.10", - "resolved": "https://registry.npmjs.org/@csstools/postcss-gradients-interpolation-method/-/postcss-gradients-interpolation-method-5.0.10.tgz", - "integrity": "sha512-HHPauB2k7Oits02tKFUeVFEU2ox/H3OQVrP3fSOKDxvloOikSal+3dzlyTZmYsb9FlY9p5EUpBtz0//XBmy+aw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/css-color-parser": "^3.0.10", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4", - "@csstools/postcss-progressive-custom-properties": "^4.1.0", - "@csstools/utilities": "^2.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-hwb-function": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/@csstools/postcss-hwb-function/-/postcss-hwb-function-4.0.10.tgz", - "integrity": "sha512-nOKKfp14SWcdEQ++S9/4TgRKchooLZL0TUFdun3nI4KPwCjETmhjta1QT4ICQcGVWQTvrsgMM/aLB5We+kMHhQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/css-color-parser": "^3.0.10", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4", - "@csstools/postcss-progressive-custom-properties": "^4.1.0", - "@csstools/utilities": "^2.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-ic-unit": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@csstools/postcss-ic-unit/-/postcss-ic-unit-4.0.2.tgz", - "integrity": "sha512-lrK2jjyZwh7DbxaNnIUjkeDmU8Y6KyzRBk91ZkI5h8nb1ykEfZrtIVArdIjX4DHMIBGpdHrgP0n4qXDr7OHaKA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/postcss-progressive-custom-properties": "^4.1.0", - "@csstools/utilities": "^2.0.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-initial": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-initial/-/postcss-initial-2.0.1.tgz", - "integrity": "sha512-L1wLVMSAZ4wovznquK0xmC7QSctzO4D0Is590bxpGqhqjboLXYA16dWZpfwImkdOgACdQ9PqXsuRroW6qPlEsg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-is-pseudo-class": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-5.0.3.tgz", - "integrity": "sha512-jS/TY4SpG4gszAtIg7Qnf3AS2pjcUM5SzxpApOrlndMeGhIbaTzWBzzP/IApXoNWEW7OhcjkRT48jnAUIFXhAQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/selector-specificity": "^5.0.0", - "postcss-selector-parser": "^7.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-is-pseudo-class/node_modules/@csstools/selector-specificity": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", - "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss-selector-parser": "^7.0.0" - } - }, - "node_modules/@csstools/postcss-is-pseudo-class/node_modules/postcss-selector-parser": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", - "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@csstools/postcss-light-dark-function": { - "version": "2.0.9", - "resolved": "https://registry.npmjs.org/@csstools/postcss-light-dark-function/-/postcss-light-dark-function-2.0.9.tgz", - "integrity": "sha512-1tCZH5bla0EAkFAI2r0H33CDnIBeLUaJh1p+hvvsylJ4svsv2wOmJjJn+OXwUZLXef37GYbRIVKX+X+g6m+3CQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4", - "@csstools/postcss-progressive-custom-properties": "^4.1.0", - "@csstools/utilities": "^2.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-logical-float-and-clear": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-float-and-clear/-/postcss-logical-float-and-clear-3.0.0.tgz", - "integrity": "sha512-SEmaHMszwakI2rqKRJgE+8rpotFfne1ZS6bZqBoQIicFyV+xT1UF42eORPxJkVJVrH9C0ctUgwMSn3BLOIZldQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-logical-overflow": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-overflow/-/postcss-logical-overflow-2.0.0.tgz", - "integrity": "sha512-spzR1MInxPuXKEX2csMamshR4LRaSZ3UXVaRGjeQxl70ySxOhMpP2252RAFsg8QyyBXBzuVOOdx1+bVO5bPIzA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-logical-overscroll-behavior": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-overscroll-behavior/-/postcss-logical-overscroll-behavior-2.0.0.tgz", - "integrity": "sha512-e/webMjoGOSYfqLunyzByZj5KKe5oyVg/YSbie99VEaSDE2kimFm0q1f6t/6Jo+VVCQ/jbe2Xy+uX+C4xzWs4w==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-logical-resize": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-resize/-/postcss-logical-resize-3.0.0.tgz", - "integrity": "sha512-DFbHQOFW/+I+MY4Ycd/QN6Dg4Hcbb50elIJCfnwkRTCX05G11SwViI5BbBlg9iHRl4ytB7pmY5ieAFk3ws7yyg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-logical-viewport-units": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-viewport-units/-/postcss-logical-viewport-units-3.0.4.tgz", - "integrity": "sha512-q+eHV1haXA4w9xBwZLKjVKAWn3W2CMqmpNpZUk5kRprvSiBEGMgrNH3/sJZ8UA3JgyHaOt3jwT9uFa4wLX4EqQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/css-tokenizer": "^3.0.4", - "@csstools/utilities": "^2.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-media-minmax": { - "version": "2.0.9", - "resolved": "https://registry.npmjs.org/@csstools/postcss-media-minmax/-/postcss-media-minmax-2.0.9.tgz", - "integrity": "sha512-af9Qw3uS3JhYLnCbqtZ9crTvvkR+0Se+bBqSr7ykAnl9yKhk6895z9rf+2F4dClIDJWxgn0iZZ1PSdkhrbs2ig==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "dependencies": { - "@csstools/css-calc": "^2.1.4", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4", - "@csstools/media-query-list-parser": "^4.0.3" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-media-queries-aspect-ratio-number-values": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@csstools/postcss-media-queries-aspect-ratio-number-values/-/postcss-media-queries-aspect-ratio-number-values-3.0.5.tgz", - "integrity": "sha512-zhAe31xaaXOY2Px8IYfoVTB3wglbJUVigGphFLj6exb7cjZRH9A6adyE22XfFK3P2PzwRk0VDeTJmaxpluyrDg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4", - "@csstools/media-query-list-parser": "^4.0.3" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-nested-calc": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-nested-calc/-/postcss-nested-calc-4.0.0.tgz", - "integrity": "sha512-jMYDdqrQQxE7k9+KjstC3NbsmC063n1FTPLCgCRS2/qHUbHM0mNy9pIn4QIiQGs9I/Bg98vMqw7mJXBxa0N88A==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/utilities": "^2.0.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-normalize-display-values": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.0.tgz", - "integrity": "sha512-HlEoG0IDRoHXzXnkV4in47dzsxdsjdz6+j7MLjaACABX2NfvjFS6XVAnpaDyGesz9gK2SC7MbNwdCHusObKJ9Q==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-oklab-function": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-4.0.10.tgz", - "integrity": "sha512-ZzZUTDd0fgNdhv8UUjGCtObPD8LYxMH+MJsW9xlZaWTV8Ppr4PtxlHYNMmF4vVWGl0T6f8tyWAKjoI6vePSgAg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/css-color-parser": "^3.0.10", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4", - "@csstools/postcss-progressive-custom-properties": "^4.1.0", - "@csstools/utilities": "^2.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-progressive-custom-properties": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-4.1.0.tgz", - "integrity": "sha512-YrkI9dx8U4R8Sz2EJaoeD9fI7s7kmeEBfmO+UURNeL6lQI7VxF6sBE+rSqdCBn4onwqmxFdBU3lTwyYb/lCmxA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-random-function": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-random-function/-/postcss-random-function-2.0.1.tgz", - "integrity": "sha512-q+FQaNiRBhnoSNo+GzqGOIBKoHQ43lYz0ICrV+UudfWnEF6ksS6DsBIJSISKQT2Bvu3g4k6r7t0zYrk5pDlo8w==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/css-calc": "^2.1.4", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-relative-color-syntax": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/@csstools/postcss-relative-color-syntax/-/postcss-relative-color-syntax-3.0.10.tgz", - "integrity": "sha512-8+0kQbQGg9yYG8hv0dtEpOMLwB9M+P7PhacgIzVzJpixxV4Eq9AUQtQw8adMmAJU1RBBmIlpmtmm3XTRd/T00g==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/css-color-parser": "^3.0.10", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4", - "@csstools/postcss-progressive-custom-properties": "^4.1.0", - "@csstools/utilities": "^2.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-scope-pseudo-class": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-scope-pseudo-class/-/postcss-scope-pseudo-class-4.0.1.tgz", - "integrity": "sha512-IMi9FwtH6LMNuLea1bjVMQAsUhFxJnyLSgOp/cpv5hrzWmrUYU5fm0EguNDIIOHUqzXode8F/1qkC/tEo/qN8Q==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "postcss-selector-parser": "^7.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-scope-pseudo-class/node_modules/postcss-selector-parser": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", - "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@csstools/postcss-sign-functions": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@csstools/postcss-sign-functions/-/postcss-sign-functions-1.1.4.tgz", - "integrity": "sha512-P97h1XqRPcfcJndFdG95Gv/6ZzxUBBISem0IDqPZ7WMvc/wlO+yU0c5D/OCpZ5TJoTt63Ok3knGk64N+o6L2Pg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/css-calc": "^2.1.4", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-stepped-value-functions": { - "version": "4.0.9", - "resolved": "https://registry.npmjs.org/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-4.0.9.tgz", - "integrity": "sha512-h9btycWrsex4dNLeQfyU3y3w40LMQooJWFMm/SK9lrKguHDcFl4VMkncKKoXi2z5rM9YGWbUQABI8BT2UydIcA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/css-calc": "^2.1.4", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-text-decoration-shorthand": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-4.0.2.tgz", - "integrity": "sha512-8XvCRrFNseBSAGxeaVTaNijAu+FzUvjwFXtcrynmazGb/9WUdsPCpBX+mHEHShVRq47Gy4peYAoxYs8ltUnmzA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/color-helpers": "^5.0.2", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-trigonometric-functions": { - "version": "4.0.9", - "resolved": "https://registry.npmjs.org/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-4.0.9.tgz", - "integrity": "sha512-Hnh5zJUdpNrJqK9v1/E3BbrQhaDTj5YiX7P61TOvUhoDHnUmsNNxcDAgkQ32RrcWx9GVUvfUNPcUkn8R3vIX6A==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/css-calc": "^2.1.4", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/postcss-unset-value": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-unset-value/-/postcss-unset-value-4.0.0.tgz", - "integrity": "sha512-cBz3tOCI5Fw6NIFEwU3RiwK6mn3nKegjpJuzCndoGq3BZPkUjnsq7uQmIeMNeMbMk7YD2MfKcgCpZwX5jyXqCA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/utilities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@csstools/utilities/-/utilities-2.0.0.tgz", - "integrity": "sha512-5VdOr0Z71u+Yp3ozOx8T11N703wIFGVRgOWbOZMKgglPJsWA54MRIoMNVMa7shUToIhx5J8vX4sOZgD2XiihiQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@discoveryjs/json-ext": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@docsearch/css": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.9.0.tgz", - "integrity": "sha512-cQbnVbq0rrBwNAKegIac/t6a8nWoUAn8frnkLFW6YARaRmAQr5/Eoe6Ln2fqkUCZ40KpdrKbpSAmgrkviOxuWA==", - "license": "MIT" - }, - "node_modules/@docsearch/react": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.9.0.tgz", - "integrity": "sha512-mb5FOZYZIkRQ6s/NWnM98k879vu5pscWqTLubLFBO87igYYT4VzVazh4h5o/zCvTIZgEt3PvsCOMOswOUo9yHQ==", - "license": "MIT", - "dependencies": { - "@algolia/autocomplete-core": "1.17.9", - "@algolia/autocomplete-preset-algolia": "1.17.9", - "@docsearch/css": "3.9.0", - "algoliasearch": "^5.14.2" - }, - "peerDependencies": { - "@types/react": ">= 16.8.0 < 20.0.0", - "react": ">= 16.8.0 < 20.0.0", - "react-dom": ">= 16.8.0 < 20.0.0", - "search-insights": ">= 1 < 3" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "react": { - "optional": true - }, - "react-dom": { - "optional": true - }, - "search-insights": { - "optional": true - } - } - }, - "node_modules/@docusaurus/babel": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/babel/-/babel-3.8.1.tgz", - "integrity": "sha512-3brkJrml8vUbn9aeoZUlJfsI/GqyFcDgQJwQkmBtclJgWDEQBKKeagZfOgx0WfUQhagL1sQLNW0iBdxnI863Uw==", - "license": "MIT", - "dependencies": { - "@babel/core": "^7.25.9", - "@babel/generator": "^7.25.9", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-transform-runtime": "^7.25.9", - "@babel/preset-env": "^7.25.9", - "@babel/preset-react": "^7.25.9", - "@babel/preset-typescript": "^7.25.9", - "@babel/runtime": "^7.25.9", - "@babel/runtime-corejs3": "^7.25.9", - "@babel/traverse": "^7.25.9", - "@docusaurus/logger": "3.8.1", - "@docusaurus/utils": "3.8.1", - "babel-plugin-dynamic-import-node": "^2.3.3", - "fs-extra": "^11.1.1", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - } - }, - "node_modules/@docusaurus/bundler": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/bundler/-/bundler-3.8.1.tgz", - "integrity": "sha512-/z4V0FRoQ0GuSLToNjOSGsk6m2lQUG4FRn8goOVoZSRsTrU8YR2aJacX5K3RG18EaX9b+52pN4m1sL3MQZVsQA==", - "license": "MIT", - "dependencies": { - "@babel/core": "^7.25.9", - "@docusaurus/babel": "3.8.1", - "@docusaurus/cssnano-preset": "3.8.1", - "@docusaurus/logger": "3.8.1", - "@docusaurus/types": "3.8.1", - "@docusaurus/utils": "3.8.1", - "babel-loader": "^9.2.1", - "clean-css": "^5.3.3", - "copy-webpack-plugin": "^11.0.0", - "css-loader": "^6.11.0", - "css-minimizer-webpack-plugin": "^5.0.1", - "cssnano": "^6.1.2", - "file-loader": "^6.2.0", - "html-minifier-terser": "^7.2.0", - "mini-css-extract-plugin": "^2.9.2", - "null-loader": "^4.0.1", - "postcss": "^8.5.4", - "postcss-loader": "^7.3.4", - "postcss-preset-env": "^10.2.1", - "terser-webpack-plugin": "^5.3.9", - "tslib": "^2.6.0", - "url-loader": "^4.1.1", - "webpack": "^5.95.0", - "webpackbar": "^6.0.1" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "@docusaurus/faster": "*" - }, - "peerDependenciesMeta": { - "@docusaurus/faster": { - "optional": true - } - } - }, - "node_modules/@docusaurus/core": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.8.1.tgz", - "integrity": "sha512-ENB01IyQSqI2FLtOzqSI3qxG2B/jP4gQPahl2C3XReiLebcVh5B5cB9KYFvdoOqOWPyr5gXK4sjgTKv7peXCrA==", - "license": "MIT", - "dependencies": { - "@docusaurus/babel": "3.8.1", - "@docusaurus/bundler": "3.8.1", - "@docusaurus/logger": "3.8.1", - "@docusaurus/mdx-loader": "3.8.1", - "@docusaurus/utils": "3.8.1", - "@docusaurus/utils-common": "3.8.1", - "@docusaurus/utils-validation": "3.8.1", - "boxen": "^6.2.1", - "chalk": "^4.1.2", - "chokidar": "^3.5.3", - "cli-table3": "^0.6.3", - "combine-promises": "^1.1.0", - "commander": "^5.1.0", - "core-js": "^3.31.1", - "detect-port": "^1.5.1", - "escape-html": "^1.0.3", - "eta": "^2.2.0", - "eval": "^0.1.8", - "execa": "5.1.1", - "fs-extra": "^11.1.1", - "html-tags": "^3.3.1", - "html-webpack-plugin": "^5.6.0", - "leven": "^3.1.0", - "lodash": "^4.17.21", - "open": "^8.4.0", - "p-map": "^4.0.0", - "prompts": "^2.4.2", - "react-helmet-async": "npm:@slorber/react-helmet-async@1.3.0", - "react-loadable": "npm:@docusaurus/react-loadable@6.0.0", - "react-loadable-ssr-addon-v5-slorber": "^1.0.1", - "react-router": "^5.3.4", - "react-router-config": "^5.1.1", - "react-router-dom": "^5.3.4", - "semver": "^7.5.4", - "serve-handler": "^6.1.6", - "tinypool": "^1.0.2", - "tslib": "^2.6.0", - "update-notifier": "^6.0.2", - "webpack": "^5.95.0", - "webpack-bundle-analyzer": "^4.10.2", - "webpack-dev-server": "^4.15.2", - "webpack-merge": "^6.0.1" - }, - "bin": { - "docusaurus": "bin/docusaurus.mjs" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "@mdx-js/react": "^3.0.0", - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - } - }, - "node_modules/@docusaurus/cssnano-preset": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-3.8.1.tgz", - "integrity": "sha512-G7WyR2N6SpyUotqhGznERBK+x84uyhfMQM2MmDLs88bw4Flom6TY46HzkRkSEzaP9j80MbTN8naiL1fR17WQug==", - "license": "MIT", - "dependencies": { - "cssnano-preset-advanced": "^6.1.2", - "postcss": "^8.5.4", - "postcss-sort-media-queries": "^5.2.0", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - } - }, - "node_modules/@docusaurus/logger": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-3.8.1.tgz", - "integrity": "sha512-2wjeGDhKcExEmjX8k1N/MRDiPKXGF2Pg+df/bDDPnnJWHXnVEZxXj80d6jcxp1Gpnksl0hF8t/ZQw9elqj2+ww==", - "license": "MIT", - "dependencies": { - "chalk": "^4.1.2", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - } - }, - "node_modules/@docusaurus/mdx-loader": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.8.1.tgz", - "integrity": "sha512-DZRhagSFRcEq1cUtBMo4TKxSNo/W6/s44yhr8X+eoXqCLycFQUylebOMPseHi5tc4fkGJqwqpWJLz6JStU9L4w==", - "license": "MIT", - "dependencies": { - "@docusaurus/logger": "3.8.1", - "@docusaurus/utils": "3.8.1", - "@docusaurus/utils-validation": "3.8.1", - "@mdx-js/mdx": "^3.0.0", - "@slorber/remark-comment": "^1.0.0", - "escape-html": "^1.0.3", - "estree-util-value-to-estree": "^3.0.1", - "file-loader": "^6.2.0", - "fs-extra": "^11.1.1", - "image-size": "^2.0.2", - "mdast-util-mdx": "^3.0.0", - "mdast-util-to-string": "^4.0.0", - "rehype-raw": "^7.0.0", - "remark-directive": "^3.0.0", - "remark-emoji": "^4.0.0", - "remark-frontmatter": "^5.0.0", - "remark-gfm": "^4.0.0", - "stringify-object": "^3.3.0", - "tslib": "^2.6.0", - "unified": "^11.0.3", - "unist-util-visit": "^5.0.0", - "url-loader": "^4.1.1", - "vfile": "^6.0.1", - "webpack": "^5.88.1" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - } - }, - "node_modules/@docusaurus/module-type-aliases": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.8.1.tgz", - "integrity": "sha512-6xhvAJiXzsaq3JdosS7wbRt/PwEPWHr9eM4YNYqVlbgG1hSK3uQDXTVvQktasp3VO6BmfYWPozueLWuj4gB+vg==", - "license": "MIT", - "dependencies": { - "@docusaurus/types": "3.8.1", - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router-config": "*", - "@types/react-router-dom": "*", - "react-helmet-async": "npm:@slorber/react-helmet-async@1.3.0", - "react-loadable": "npm:@docusaurus/react-loadable@6.0.0" - }, - "peerDependencies": { - "react": "*", - "react-dom": "*" - } - }, - "node_modules/@docusaurus/plugin-content-blog": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.8.1.tgz", - "integrity": "sha512-vNTpMmlvNP9n3hGEcgPaXyvTljanAKIUkuG9URQ1DeuDup0OR7Ltvoc8yrmH+iMZJbcQGhUJF+WjHLwuk8HSdw==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.8.1", - "@docusaurus/logger": "3.8.1", - "@docusaurus/mdx-loader": "3.8.1", - "@docusaurus/theme-common": "3.8.1", - "@docusaurus/types": "3.8.1", - "@docusaurus/utils": "3.8.1", - "@docusaurus/utils-common": "3.8.1", - "@docusaurus/utils-validation": "3.8.1", - "cheerio": "1.0.0-rc.12", - "feed": "^4.2.2", - "fs-extra": "^11.1.1", - "lodash": "^4.17.21", - "schema-dts": "^1.1.2", - "srcset": "^4.0.0", - "tslib": "^2.6.0", - "unist-util-visit": "^5.0.0", - "utility-types": "^3.10.0", - "webpack": "^5.88.1" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "@docusaurus/plugin-content-docs": "*", - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - } - }, - "node_modules/@docusaurus/plugin-content-docs": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.8.1.tgz", - "integrity": "sha512-oByRkSZzeGNQByCMaX+kif5Nl2vmtj2IHQI2fWjCfCootsdKZDPFLonhIp5s3IGJO7PLUfe0POyw0Xh/RrGXJA==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.8.1", - "@docusaurus/logger": "3.8.1", - "@docusaurus/mdx-loader": "3.8.1", - "@docusaurus/module-type-aliases": "3.8.1", - "@docusaurus/theme-common": "3.8.1", - "@docusaurus/types": "3.8.1", - "@docusaurus/utils": "3.8.1", - "@docusaurus/utils-common": "3.8.1", - "@docusaurus/utils-validation": "3.8.1", - "@types/react-router-config": "^5.0.7", - "combine-promises": "^1.1.0", - "fs-extra": "^11.1.1", - "js-yaml": "^4.1.0", - "lodash": "^4.17.21", - "schema-dts": "^1.1.2", - "tslib": "^2.6.0", - "utility-types": "^3.10.0", - "webpack": "^5.88.1" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - } - }, - "node_modules/@docusaurus/plugin-content-pages": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.8.1.tgz", - "integrity": "sha512-a+V6MS2cIu37E/m7nDJn3dcxpvXb6TvgdNI22vJX8iUTp8eoMoPa0VArEbWvCxMY/xdC26WzNv4wZ6y0iIni/w==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.8.1", - "@docusaurus/mdx-loader": "3.8.1", - "@docusaurus/types": "3.8.1", - "@docusaurus/utils": "3.8.1", - "@docusaurus/utils-validation": "3.8.1", - "fs-extra": "^11.1.1", - "tslib": "^2.6.0", - "webpack": "^5.88.1" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - } - }, - "node_modules/@docusaurus/plugin-css-cascade-layers": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-css-cascade-layers/-/plugin-css-cascade-layers-3.8.1.tgz", - "integrity": "sha512-VQ47xRxfNKjHS5ItzaVXpxeTm7/wJLFMOPo1BkmoMG4Cuz4nuI+Hs62+RMk1OqVog68Swz66xVPK8g9XTrBKRw==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.8.1", - "@docusaurus/types": "3.8.1", - "@docusaurus/utils": "3.8.1", - "@docusaurus/utils-validation": "3.8.1", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - } - }, - "node_modules/@docusaurus/plugin-debug": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-debug/-/plugin-debug-3.8.1.tgz", - "integrity": "sha512-nT3lN7TV5bi5hKMB7FK8gCffFTBSsBsAfV84/v293qAmnHOyg1nr9okEw8AiwcO3bl9vije5nsUvP0aRl2lpaw==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.8.1", - "@docusaurus/types": "3.8.1", - "@docusaurus/utils": "3.8.1", - "fs-extra": "^11.1.1", - "react-json-view-lite": "^2.3.0", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - } - }, - "node_modules/@docusaurus/plugin-google-analytics": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.8.1.tgz", - "integrity": "sha512-Hrb/PurOJsmwHAsfMDH6oVpahkEGsx7F8CWMjyP/dw1qjqmdS9rcV1nYCGlM8nOtD3Wk/eaThzUB5TSZsGz+7Q==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.8.1", - "@docusaurus/types": "3.8.1", - "@docusaurus/utils-validation": "3.8.1", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - } - }, - "node_modules/@docusaurus/plugin-google-gtag": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.8.1.tgz", - "integrity": "sha512-tKE8j1cEZCh8KZa4aa80zpSTxsC2/ZYqjx6AAfd8uA8VHZVw79+7OTEP2PoWi0uL5/1Is0LF5Vwxd+1fz5HlKg==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.8.1", - "@docusaurus/types": "3.8.1", - "@docusaurus/utils-validation": "3.8.1", - "@types/gtag.js": "^0.0.12", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - } - }, - "node_modules/@docusaurus/plugin-google-tag-manager": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.8.1.tgz", - "integrity": "sha512-iqe3XKITBquZq+6UAXdb1vI0fPY5iIOitVjPQ581R1ZKpHr0qe+V6gVOrrcOHixPDD/BUKdYwkxFjpNiEN+vBw==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.8.1", - "@docusaurus/types": "3.8.1", - "@docusaurus/utils-validation": "3.8.1", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - } - }, - "node_modules/@docusaurus/plugin-sitemap": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.8.1.tgz", - "integrity": "sha512-+9YV/7VLbGTq8qNkjiugIelmfUEVkTyLe6X8bWq7K5qPvGXAjno27QAfFq63mYfFFbJc7z+pudL63acprbqGzw==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.8.1", - "@docusaurus/logger": "3.8.1", - "@docusaurus/types": "3.8.1", - "@docusaurus/utils": "3.8.1", - "@docusaurus/utils-common": "3.8.1", - "@docusaurus/utils-validation": "3.8.1", - "fs-extra": "^11.1.1", - "sitemap": "^7.1.1", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - } - }, - "node_modules/@docusaurus/plugin-svgr": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-svgr/-/plugin-svgr-3.8.1.tgz", - "integrity": "sha512-rW0LWMDsdlsgowVwqiMb/7tANDodpy1wWPwCcamvhY7OECReN3feoFwLjd/U4tKjNY3encj0AJSTxJA+Fpe+Gw==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.8.1", - "@docusaurus/types": "3.8.1", - "@docusaurus/utils": "3.8.1", - "@docusaurus/utils-validation": "3.8.1", - "@svgr/core": "8.1.0", - "@svgr/webpack": "^8.1.0", - "tslib": "^2.6.0", - "webpack": "^5.88.1" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - } - }, - "node_modules/@docusaurus/preset-classic": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-3.8.1.tgz", - "integrity": "sha512-yJSjYNHXD8POMGc2mKQuj3ApPrN+eG0rO1UPgSx7jySpYU+n4WjBikbrA2ue5ad9A7aouEtMWUoiSRXTH/g7KQ==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.8.1", - "@docusaurus/plugin-content-blog": "3.8.1", - "@docusaurus/plugin-content-docs": "3.8.1", - "@docusaurus/plugin-content-pages": "3.8.1", - "@docusaurus/plugin-css-cascade-layers": "3.8.1", - "@docusaurus/plugin-debug": "3.8.1", - "@docusaurus/plugin-google-analytics": "3.8.1", - "@docusaurus/plugin-google-gtag": "3.8.1", - "@docusaurus/plugin-google-tag-manager": "3.8.1", - "@docusaurus/plugin-sitemap": "3.8.1", - "@docusaurus/plugin-svgr": "3.8.1", - "@docusaurus/theme-classic": "3.8.1", - "@docusaurus/theme-common": "3.8.1", - "@docusaurus/theme-search-algolia": "3.8.1", - "@docusaurus/types": "3.8.1" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - } - }, - "node_modules/@docusaurus/theme-classic": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-3.8.1.tgz", - "integrity": "sha512-bqDUCNqXeYypMCsE1VcTXSI1QuO4KXfx8Cvl6rYfY0bhhqN6d2WZlRkyLg/p6pm+DzvanqHOyYlqdPyP0iz+iw==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "3.8.1", - "@docusaurus/logger": "3.8.1", - "@docusaurus/mdx-loader": "3.8.1", - "@docusaurus/module-type-aliases": "3.8.1", - "@docusaurus/plugin-content-blog": "3.8.1", - "@docusaurus/plugin-content-docs": "3.8.1", - "@docusaurus/plugin-content-pages": "3.8.1", - "@docusaurus/theme-common": "3.8.1", - "@docusaurus/theme-translations": "3.8.1", - "@docusaurus/types": "3.8.1", - "@docusaurus/utils": "3.8.1", - "@docusaurus/utils-common": "3.8.1", - "@docusaurus/utils-validation": "3.8.1", - "@mdx-js/react": "^3.0.0", - "clsx": "^2.0.0", - "copy-text-to-clipboard": "^3.2.0", - "infima": "0.2.0-alpha.45", - "lodash": "^4.17.21", - "nprogress": "^0.2.0", - "postcss": "^8.5.4", - "prism-react-renderer": "^2.3.0", - "prismjs": "^1.29.0", - "react-router-dom": "^5.3.4", - "rtlcss": "^4.1.0", - "tslib": "^2.6.0", - "utility-types": "^3.10.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - } - }, - "node_modules/@docusaurus/theme-common": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.8.1.tgz", - "integrity": "sha512-UswMOyTnPEVRvN5Qzbo+l8k4xrd5fTFu2VPPfD6FcW/6qUtVLmJTQCktbAL3KJ0BVXGm5aJXz/ZrzqFuZERGPw==", - "license": "MIT", - "dependencies": { - "@docusaurus/mdx-loader": "3.8.1", - "@docusaurus/module-type-aliases": "3.8.1", - "@docusaurus/utils": "3.8.1", - "@docusaurus/utils-common": "3.8.1", - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router-config": "*", - "clsx": "^2.0.0", - "parse-numeric-range": "^1.3.0", - "prism-react-renderer": "^2.3.0", - "tslib": "^2.6.0", - "utility-types": "^3.10.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "@docusaurus/plugin-content-docs": "*", - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - } - }, - "node_modules/@docusaurus/theme-search-algolia": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.8.1.tgz", - "integrity": "sha512-NBFH5rZVQRAQM087aYSRKQ9yGEK9eHd+xOxQjqNpxMiV85OhJDD4ZGz6YJIod26Fbooy54UWVdzNU0TFeUUUzQ==", - "license": "MIT", - "dependencies": { - "@docsearch/react": "^3.9.0", - "@docusaurus/core": "3.8.1", - "@docusaurus/logger": "3.8.1", - "@docusaurus/plugin-content-docs": "3.8.1", - "@docusaurus/theme-common": "3.8.1", - "@docusaurus/theme-translations": "3.8.1", - "@docusaurus/utils": "3.8.1", - "@docusaurus/utils-validation": "3.8.1", - "algoliasearch": "^5.17.1", - "algoliasearch-helper": "^3.22.6", - "clsx": "^2.0.0", - "eta": "^2.2.0", - "fs-extra": "^11.1.1", - "lodash": "^4.17.21", - "tslib": "^2.6.0", - "utility-types": "^3.10.0" - }, - "engines": { - "node": ">=18.0" - }, - "peerDependencies": { - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - } - }, - "node_modules/@docusaurus/theme-translations": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-translations/-/theme-translations-3.8.1.tgz", - "integrity": "sha512-OTp6eebuMcf2rJt4bqnvuwmm3NVXfzfYejL+u/Y1qwKhZPrjPoKWfk1CbOP5xH5ZOPkiAsx4dHdQBRJszK3z2g==", - "license": "MIT", - "dependencies": { - "fs-extra": "^11.1.1", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - } - }, - "node_modules/@docusaurus/tsconfig": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/tsconfig/-/tsconfig-3.8.1.tgz", - "integrity": "sha512-XBWCcqhRHhkhfolnSolNL+N7gj3HVE3CoZVqnVjfsMzCoOsuQw2iCLxVVHtO+rePUUfouVZHURDgmqIySsF66A==", - "dev": true, - "license": "MIT" - }, - "node_modules/@docusaurus/types": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.8.1.tgz", - "integrity": "sha512-ZPdW5AB+pBjiVrcLuw3dOS6BFlrG0XkS2lDGsj8TizcnREQg3J8cjsgfDviszOk4CweNfwo1AEELJkYaMUuOPg==", - "license": "MIT", - "dependencies": { - "@mdx-js/mdx": "^3.0.0", - "@types/history": "^4.7.11", - "@types/react": "*", - "commander": "^5.1.0", - "joi": "^17.9.2", - "react-helmet-async": "npm:@slorber/react-helmet-async@1.3.0", - "utility-types": "^3.10.0", - "webpack": "^5.95.0", - "webpack-merge": "^5.9.0" - }, - "peerDependencies": { - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - } - }, - "node_modules/@docusaurus/types/node_modules/webpack-merge": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", - "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", - "license": "MIT", - "dependencies": { - "clone-deep": "^4.0.1", - "flat": "^5.0.2", - "wildcard": "^2.0.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@docusaurus/utils": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.8.1.tgz", - "integrity": "sha512-P1ml0nvOmEFdmu0smSXOqTS1sxU5tqvnc0dA4MTKV39kye+bhQnjkIKEE18fNOvxjyB86k8esoCIFM3x4RykOQ==", - "license": "MIT", - "dependencies": { - "@docusaurus/logger": "3.8.1", - "@docusaurus/types": "3.8.1", - "@docusaurus/utils-common": "3.8.1", - "escape-string-regexp": "^4.0.0", - "execa": "5.1.1", - "file-loader": "^6.2.0", - "fs-extra": "^11.1.1", - "github-slugger": "^1.5.0", - "globby": "^11.1.0", - "gray-matter": "^4.0.3", - "jiti": "^1.20.0", - "js-yaml": "^4.1.0", - "lodash": "^4.17.21", - "micromatch": "^4.0.5", - "p-queue": "^6.6.2", - "prompts": "^2.4.2", - "resolve-pathname": "^3.0.0", - "tslib": "^2.6.0", - "url-loader": "^4.1.1", - "utility-types": "^3.10.0", - "webpack": "^5.88.1" - }, - "engines": { - "node": ">=18.0" - } - }, - "node_modules/@docusaurus/utils-common": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-3.8.1.tgz", - "integrity": "sha512-zTZiDlvpvoJIrQEEd71c154DkcriBecm4z94OzEE9kz7ikS3J+iSlABhFXM45mZ0eN5pVqqr7cs60+ZlYLewtg==", - "license": "MIT", - "dependencies": { - "@docusaurus/types": "3.8.1", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - } - }, - "node_modules/@docusaurus/utils-validation": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-3.8.1.tgz", - "integrity": "sha512-gs5bXIccxzEbyVecvxg6upTwaUbfa0KMmTj7HhHzc016AGyxH2o73k1/aOD0IFrdCsfJNt37MqNI47s2MgRZMA==", - "license": "MIT", - "dependencies": { - "@docusaurus/logger": "3.8.1", - "@docusaurus/utils": "3.8.1", - "@docusaurus/utils-common": "3.8.1", - "fs-extra": "^11.2.0", - "joi": "^17.9.2", - "js-yaml": "^4.1.0", - "lodash": "^4.17.21", - "tslib": "^2.6.0" - }, - "engines": { - "node": ">=18.0" - } - }, - "node_modules/@hapi/hoek": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", - "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==", - "license": "BSD-3-Clause" - }, - "node_modules/@hapi/topo": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", - "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", - "license": "BSD-3-Clause", - "dependencies": { - "@hapi/hoek": "^9.0.0" - } - }, - "node_modules/@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.27.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/types": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", - "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", - "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", - "license": "MIT", - "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==", - "license": "MIT", - "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==", - "license": "MIT", - "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==", - "license": "MIT", - "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==", - "license": "MIT" - }, - "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==", - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@leichtgewicht/ip-codec": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", - "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", - "license": "MIT" - }, - "node_modules/@mdx-js/mdx": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.1.0.tgz", - "integrity": "sha512-/QxEhPAvGwbQmy1Px8F899L5Uc2KZ6JtXwlCgJmjSTBedwOZkByYcBG4GceIGPXRDsmfxhHazuS+hlOShRLeDw==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdx": "^2.0.0", - "collapse-white-space": "^2.0.0", - "devlop": "^1.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "estree-util-scope": "^1.0.0", - "estree-walker": "^3.0.0", - "hast-util-to-jsx-runtime": "^2.0.0", - "markdown-extensions": "^2.0.0", - "recma-build-jsx": "^1.0.0", - "recma-jsx": "^1.0.0", - "recma-stringify": "^1.0.0", - "rehype-recma": "^1.0.0", - "remark-mdx": "^3.0.0", - "remark-parse": "^11.0.0", - "remark-rehype": "^11.0.0", - "source-map": "^0.7.0", - "unified": "^11.0.0", - "unist-util-position-from-estree": "^2.0.0", - "unist-util-stringify-position": "^4.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@mdx-js/react": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.0.tgz", - "integrity": "sha512-QjHtSaoameoalGnKDT3FoIl4+9RwyTmo9ZJGBdLOks/YOiWHoRDI3PUwEzOE7kEmGcV3AFcp9K6dYu9rEuKLAQ==", - "license": "MIT", - "dependencies": { - "@types/mdx": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - }, - "peerDependencies": { - "@types/react": ">=16", - "react": ">=16" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@pnpm/config.env-replace": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", - "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==", - "license": "MIT", - "engines": { - "node": ">=12.22.0" - } - }, - "node_modules/@pnpm/network.ca-file": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", - "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==", - "license": "MIT", - "dependencies": { - "graceful-fs": "4.2.10" - }, - "engines": { - "node": ">=12.22.0" - } - }, - "node_modules/@pnpm/network.ca-file/node_modules/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "license": "ISC" - }, - "node_modules/@pnpm/npm-conf": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.3.1.tgz", - "integrity": "sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw==", - "license": "MIT", - "dependencies": { - "@pnpm/config.env-replace": "^1.1.0", - "@pnpm/network.ca-file": "^1.0.1", - "config-chain": "^1.1.11" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@polka/url": { - "version": "1.0.0-next.29", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", - "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", - "license": "MIT" - }, - "node_modules/@sideway/address": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", - "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", - "license": "BSD-3-Clause", - "dependencies": { - "@hapi/hoek": "^9.0.0" - } - }, - "node_modules/@sideway/formula": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", - "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==", - "license": "BSD-3-Clause" - }, - "node_modules/@sideway/pinpoint": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", - "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", - "license": "BSD-3-Clause" - }, - "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", - "license": "MIT" - }, - "node_modules/@sindresorhus/is": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, - "node_modules/@slorber/remark-comment": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@slorber/remark-comment/-/remark-comment-1.0.0.tgz", - "integrity": "sha512-RCE24n7jsOj1M0UPvIQCHTe7fI0sFL4S2nwKVWwHyVr/wI/H8GosgsJGyhnsZoGFnD/P2hLf1mSbrrgSLN93NA==", - "license": "MIT", - "dependencies": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.1.0", - "micromark-util-symbol": "^1.0.1" - } - }, - "node_modules/@svgr/babel-plugin-add-jsx-attribute": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz", - "integrity": "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==", - "license": "MIT", - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz", - "integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==", - "license": "MIT", - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz", - "integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==", - "license": "MIT", - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz", - "integrity": "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==", - "license": "MIT", - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-svg-dynamic-title": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz", - "integrity": "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==", - "license": "MIT", - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-svg-em-dimensions": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz", - "integrity": "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==", - "license": "MIT", - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-transform-react-native-svg": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz", - "integrity": "sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==", - "license": "MIT", - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-plugin-transform-svg-component": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz", - "integrity": "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/babel-preset": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz", - "integrity": "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==", - "license": "MIT", - "dependencies": { - "@svgr/babel-plugin-add-jsx-attribute": "8.0.0", - "@svgr/babel-plugin-remove-jsx-attribute": "8.0.0", - "@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0", - "@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0", - "@svgr/babel-plugin-svg-dynamic-title": "8.0.0", - "@svgr/babel-plugin-svg-em-dimensions": "8.0.0", - "@svgr/babel-plugin-transform-react-native-svg": "8.1.0", - "@svgr/babel-plugin-transform-svg-component": "8.0.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@svgr/core": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz", - "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", - "license": "MIT", - "dependencies": { - "@babel/core": "^7.21.3", - "@svgr/babel-preset": "8.1.0", - "camelcase": "^6.2.0", - "cosmiconfig": "^8.1.3", - "snake-case": "^3.0.4" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/hast-util-to-babel-ast": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz", - "integrity": "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.21.3", - "entities": "^4.4.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/plugin-jsx": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz", - "integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==", - "license": "MIT", - "dependencies": { - "@babel/core": "^7.21.3", - "@svgr/babel-preset": "8.1.0", - "@svgr/hast-util-to-babel-ast": "8.0.0", - "svg-parser": "^2.0.4" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@svgr/core": "*" - } - }, - "node_modules/@svgr/plugin-svgo": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-8.1.0.tgz", - "integrity": "sha512-Ywtl837OGO9pTLIN/onoWLmDQ4zFUycI1g76vuKGEz6evR/ZTJlJuz3G/fIkb6OVBJ2g0o6CGJzaEjfmEo3AHA==", - "license": "MIT", - "dependencies": { - "cosmiconfig": "^8.1.3", - "deepmerge": "^4.3.1", - "svgo": "^3.0.2" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - }, - "peerDependencies": { - "@svgr/core": "*" - } - }, - "node_modules/@svgr/webpack": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-8.1.0.tgz", - "integrity": "sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA==", - "license": "MIT", - "dependencies": { - "@babel/core": "^7.21.3", - "@babel/plugin-transform-react-constant-elements": "^7.21.3", - "@babel/preset-env": "^7.20.2", - "@babel/preset-react": "^7.18.6", - "@babel/preset-typescript": "^7.21.0", - "@svgr/core": "8.1.0", - "@svgr/plugin-jsx": "8.1.0", - "@svgr/plugin-svgo": "8.1.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@szmarczak/http-timer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", - "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", - "license": "MIT", - "dependencies": { - "defer-to-connect": "^2.0.1" - }, - "engines": { - "node": ">=14.16" - } - }, - "node_modules/@trysound/sax": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", - "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", - "license": "ISC", - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/@types/body-parser": { - "version": "1.19.6", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", - "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", - "license": "MIT", - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "node_modules/@types/bonjour": { - "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", - "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/connect-history-api-fallback": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", - "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", - "license": "MIT", - "dependencies": { - "@types/express-serve-static-core": "*", - "@types/node": "*" - } - }, - "node_modules/@types/debug": { - "version": "4.1.12", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", - "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", - "license": "MIT", - "dependencies": { - "@types/ms": "*" - } - }, - "node_modules/@types/eslint": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", - "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", - "license": "MIT", - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "node_modules/@types/eslint-scope": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", - "license": "MIT", - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "license": "MIT" - }, - "node_modules/@types/estree-jsx": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", - "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", - "license": "MIT", - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/@types/express": { - "version": "4.17.23", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.23.tgz", - "integrity": "sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ==", - "license": "MIT", - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "node_modules/@types/express-serve-static-core": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.6.tgz", - "integrity": "sha512-3xhRnjJPkULekpSzgtoNYYcTWgEZkp4myc+Saevii5JPnHNvHMRlBSHDbs7Bh1iPPoVTERHEZXyhyLbMEsExsA==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, - "node_modules/@types/express/node_modules/@types/express-serve-static-core": { - "version": "4.19.6", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", - "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, - "node_modules/@types/gtag.js": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/@types/gtag.js/-/gtag.js-0.0.12.tgz", - "integrity": "sha512-YQV9bUsemkzG81Ea295/nF/5GijnD2Af7QhEofh7xu+kvCN6RdodgNwwGWXB5GMI3NoyvQo0odNctoH/qLMIpg==", - "license": "MIT" - }, - "node_modules/@types/hast": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", - "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@types/history": { - "version": "4.7.11", - "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", - "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==", - "license": "MIT" - }, - "node_modules/@types/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==", - "license": "MIT" - }, - "node_modules/@types/http-cache-semantics": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", - "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", - "license": "MIT" - }, - "node_modules/@types/http-errors": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", - "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", - "license": "MIT" - }, - "node_modules/@types/http-proxy": { - "version": "1.17.16", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.16.tgz", - "integrity": "sha512-sdWoUajOB1cd0A8cRRQ1cfyWNbmFKLAqBB89Y8x5iYyG/mkJHc0YUH8pdWBy2omi9qtCpiIgGjuwO0dQST2l5w==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", - "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", - "license": "MIT" - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", - "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", - "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "license": "MIT" - }, - "node_modules/@types/mdast": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", - "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", - "license": "MIT", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@types/mdx": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz", - "integrity": "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==", - "license": "MIT" - }, - "node_modules/@types/mime": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", - "license": "MIT" - }, - "node_modules/@types/ms": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", - "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "24.0.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.3.tgz", - "integrity": "sha512-R4I/kzCYAdRLzfiCabn9hxWfbuHS573x+r0dJMkkzThEa7pbrcDWK+9zu3e7aBOouf+rQAciqPFMnxwr0aWgKg==", - "license": "MIT", - "dependencies": { - "undici-types": "~7.8.0" - } - }, - "node_modules/@types/node-forge": { - "version": "1.3.11", - "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", - "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/prismjs": { - "version": "1.26.5", - "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.5.tgz", - "integrity": "sha512-AUZTa7hQ2KY5L7AmtSiqxlhWxb4ina0yd8hNbl4TWuqnv/pFP0nDMb3YrfSBf4hJVGLh2YEIBfKaBW/9UEl6IQ==", - "license": "MIT" - }, - "node_modules/@types/qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==", - "license": "MIT" - }, - "node_modules/@types/range-parser": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", - "license": "MIT" - }, - "node_modules/@types/react": { - "version": "19.1.8", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.8.tgz", - "integrity": "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==", - "license": "MIT", - "dependencies": { - "csstype": "^3.0.2" - } - }, - "node_modules/@types/react-router": { - "version": "5.1.20", - "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.20.tgz", - "integrity": "sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==", - "license": "MIT", - "dependencies": { - "@types/history": "^4.7.11", - "@types/react": "*" - } - }, - "node_modules/@types/react-router-config": { - "version": "5.0.11", - "resolved": "https://registry.npmjs.org/@types/react-router-config/-/react-router-config-5.0.11.tgz", - "integrity": "sha512-WmSAg7WgqW7m4x8Mt4N6ZyKz0BubSj/2tVUMsAHp+Yd2AMwcSbeFq9WympT19p5heCFmF97R9eD5uUR/t4HEqw==", - "license": "MIT", - "dependencies": { - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router": "^5.1.0" - } - }, - "node_modules/@types/react-router-dom": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz", - "integrity": "sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==", - "license": "MIT", - "dependencies": { - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router": "*" - } - }, - "node_modules/@types/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", - "license": "MIT" - }, - "node_modules/@types/sax": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz", - "integrity": "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/send": { - "version": "0.17.5", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.5.tgz", - "integrity": "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==", - "license": "MIT", - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "node_modules/@types/serve-index": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", - "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", - "license": "MIT", - "dependencies": { - "@types/express": "*" - } - }, - "node_modules/@types/serve-static": { - "version": "1.15.8", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.8.tgz", - "integrity": "sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==", - "license": "MIT", - "dependencies": { - "@types/http-errors": "*", - "@types/node": "*", - "@types/send": "*" - } - }, - "node_modules/@types/sockjs": { - "version": "0.3.36", - "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", - "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", - "license": "MIT" - }, - "node_modules/@types/ws": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", - "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/yargs": { - "version": "17.0.33", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", - "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", - "license": "MIT" - }, - "node_modules/@ungap/structured-clone": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", - "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", - "license": "ISC" - }, - "node_modules/@webassemblyjs/ast": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", - "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/helper-numbers": "1.13.2", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2" - } - }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", - "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", - "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", - "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", - "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.13.2", - "@webassemblyjs/helper-api-error": "1.13.2", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", - "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", - "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-buffer": "1.14.1", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/wasm-gen": "1.14.1" - } - }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", - "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", - "license": "MIT", - "dependencies": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", - "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", - "license": "Apache-2.0", - "dependencies": { - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", - "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", - "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-buffer": "1.14.1", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/helper-wasm-section": "1.14.1", - "@webassemblyjs/wasm-gen": "1.14.1", - "@webassemblyjs/wasm-opt": "1.14.1", - "@webassemblyjs/wasm-parser": "1.14.1", - "@webassemblyjs/wast-printer": "1.14.1" - } - }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", - "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/ieee754": "1.13.2", - "@webassemblyjs/leb128": "1.13.2", - "@webassemblyjs/utf8": "1.13.2" - } - }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", - "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-buffer": "1.14.1", - "@webassemblyjs/wasm-gen": "1.14.1", - "@webassemblyjs/wasm-parser": "1.14.1" - } - }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", - "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-api-error": "1.13.2", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/ieee754": "1.13.2", - "@webassemblyjs/leb128": "1.13.2", - "@webassemblyjs/utf8": "1.13.2" - } - }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", - "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "license": "BSD-3-Clause" - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "license": "Apache-2.0" - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "license": "MIT", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/accepts/node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/accepts/node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/accepts/node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", - "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", - "license": "MIT", - "dependencies": { - "acorn": "^8.11.0" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/address": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", - "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==", - "license": "MIT", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "license": "MIT", - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/algoliasearch": { - "version": "5.29.0", - "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.29.0.tgz", - "integrity": "sha512-E2l6AlTWGznM2e7vEE6T6hzObvEyXukxMOlBmVlMyixZyK1umuO/CiVc6sDBbzVH0oEviCE5IfVY1oZBmccYPQ==", - "license": "MIT", - "dependencies": { - "@algolia/client-abtesting": "5.29.0", - "@algolia/client-analytics": "5.29.0", - "@algolia/client-common": "5.29.0", - "@algolia/client-insights": "5.29.0", - "@algolia/client-personalization": "5.29.0", - "@algolia/client-query-suggestions": "5.29.0", - "@algolia/client-search": "5.29.0", - "@algolia/ingestion": "1.29.0", - "@algolia/monitoring": "1.29.0", - "@algolia/recommend": "5.29.0", - "@algolia/requester-browser-xhr": "5.29.0", - "@algolia/requester-fetch": "5.29.0", - "@algolia/requester-node-http": "5.29.0" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/algoliasearch-helper": { - "version": "3.26.0", - "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.26.0.tgz", - "integrity": "sha512-Rv2x3GXleQ3ygwhkhJubhhYGsICmShLAiqtUuJTUkr9uOCOXyF2E71LVT4XDnVffbknv8XgScP4U0Oxtgm+hIw==", - "license": "MIT", - "dependencies": { - "@algolia/events": "^4.0.1" - }, - "peerDependencies": { - "algoliasearch": ">= 3.1 < 6" - } - }, - "node_modules/ansi-align": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", - "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", - "license": "ISC", - "dependencies": { - "string-width": "^4.1.0" - } - }, - "node_modules/ansi-align/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/ansi-align/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "license": "MIT", - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-html-community": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", - "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", - "engines": [ - "node >= 0.8.0" - ], - "license": "Apache-2.0", - "bin": { - "ansi-html": "bin/ansi-html" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/arg": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", - "license": "MIT" - }, - "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==", - "license": "Python-2.0" - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "license": "MIT" - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/astring": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/astring/-/astring-1.9.0.tgz", - "integrity": "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==", - "license": "MIT", - "bin": { - "astring": "bin/astring" - } - }, - "node_modules/autoprefixer": { - "version": "10.4.21", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz", - "integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "browserslist": "^4.24.4", - "caniuse-lite": "^1.0.30001702", - "fraction.js": "^4.3.7", - "normalize-range": "^0.1.2", - "picocolors": "^1.1.1", - "postcss-value-parser": "^4.2.0" - }, - "bin": { - "autoprefixer": "bin/autoprefixer" - }, - "engines": { - "node": "^10 || ^12 || >=14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/babel-loader": { - "version": "9.2.1", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.2.1.tgz", - "integrity": "sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA==", - "license": "MIT", - "dependencies": { - "find-cache-dir": "^4.0.0", - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 14.15.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0", - "webpack": ">=5" - } - }, - "node_modules/babel-plugin-dynamic-import-node": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", - "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", - "license": "MIT", - "dependencies": { - "object.assign": "^4.1.0" - } - }, - "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.13", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.13.tgz", - "integrity": "sha512-3sX/eOms8kd3q2KZ6DAhKPc0dgm525Gqq5NtWKZ7QYYZEv57OQ54KtblzJzH1lQF/eQxO8KjWGIK9IPUJNus5g==", - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.6.4", - "semver": "^6.3.1" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.11.1.tgz", - "integrity": "sha512-yGCqvBT4rwMczo28xkH/noxJ6MZ4nJfkVYdoDaC/utLtWrXxv27HVrzAeSbqR8SxDsp46n0YF47EbHoixy6rXQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.3", - "core-js-compat": "^3.40.0" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.4.tgz", - "integrity": "sha512-7gD3pRadPrbjhjLyxebmx/WrFYcuSjZ0XbdUujQMZ/fcE9oeewk2U/7PCvez84UeuK3oSjmPZ0Ch0dlupQvGzw==", - "license": "MIT", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.4" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/bail": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", - "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "license": "MIT" - }, - "node_modules/batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", - "license": "MIT" - }, - "node_modules/big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/body-parser": { - "version": "1.20.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", - "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.13.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/body-parser/node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/bonjour-service": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.3.0.tgz", - "integrity": "sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "multicast-dns": "^7.2.5" - } - }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "license": "ISC" - }, - "node_modules/boxen": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-6.2.1.tgz", - "integrity": "sha512-H4PEsJXfFI/Pt8sjDWbHlQPx4zL/bvSQjcilJmaulGt5mLDorHOHpmdXAJcBcmru7PhYSp/cDMWRko4ZUMFkSw==", - "license": "MIT", - "dependencies": { - "ansi-align": "^3.0.1", - "camelcase": "^6.2.0", - "chalk": "^4.1.2", - "cli-boxes": "^3.0.0", - "string-width": "^5.0.1", - "type-fest": "^2.5.0", - "widest-line": "^4.0.1", - "wrap-ansi": "^8.0.1" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserslist": { - "version": "4.25.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.0.tgz", - "integrity": "sha512-PJ8gYKeS5e/whHBh8xrwYK+dAvEj7JXtz6uTucnMRB8OiGTsKccFekoRrjajPBHV8oOY+2tI4uxeceSimKwMFA==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "caniuse-lite": "^1.0.30001718", - "electron-to-chromium": "^1.5.160", - "node-releases": "^2.0.19", - "update-browserslist-db": "^1.1.3" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "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==", - "license": "MIT" - }, - "node_modules/bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/cacheable-lookup": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", - "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", - "license": "MIT", - "engines": { - "node": ">=14.16" - } - }, - "node_modules/cacheable-request": { - "version": "10.2.14", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz", - "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==", - "license": "MIT", - "dependencies": { - "@types/http-cache-semantics": "^4.0.2", - "get-stream": "^6.0.1", - "http-cache-semantics": "^4.1.1", - "keyv": "^4.5.3", - "mimic-response": "^4.0.0", - "normalize-url": "^8.0.0", - "responselike": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - } - }, - "node_modules/call-bind": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", - "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.0", - "es-define-property": "^1.0.0", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/call-bound": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/camel-case": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", - "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", - "license": "MIT", - "dependencies": { - "pascal-case": "^3.1.2", - "tslib": "^2.0.3" - } - }, - "node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/caniuse-api": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", - "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", - "license": "MIT", - "dependencies": { - "browserslist": "^4.0.0", - "caniuse-lite": "^1.0.0", - "lodash.memoize": "^4.1.2", - "lodash.uniq": "^4.5.0" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001724", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001724.tgz", - "integrity": "sha512-WqJo7p0TbHDOythNTqYujmaJTvtYRZrjpP8TCvH6Vb9CYJerJNKamKzIWOM4BkQatWj9H2lYulpdAQNBe7QhNA==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" - }, - "node_modules/ccount": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", - "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/character-entities": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", - "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-entities-html4": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", - "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-entities-legacy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", - "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-reference-invalid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", - "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/cheerio": { - "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", - "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", - "license": "MIT", - "dependencies": { - "cheerio-select": "^2.1.0", - "dom-serializer": "^2.0.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "htmlparser2": "^8.0.1", - "parse5": "^7.0.0", - "parse5-htmlparser2-tree-adapter": "^7.0.0" - }, - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/cheeriojs/cheerio?sponsor=1" - } - }, - "node_modules/cheerio-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", - "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0", - "css-select": "^5.1.0", - "css-what": "^6.1.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "license": "MIT", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chrome-trace-event": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", - "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", - "license": "MIT", - "engines": { - "node": ">=6.0" - } - }, - "node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/clean-css": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", - "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==", - "license": "MIT", - "dependencies": { - "source-map": "~0.6.0" - }, - "engines": { - "node": ">= 10.0" - } - }, - "node_modules/clean-css/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==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/cli-boxes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", - "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cli-table3": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", - "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", - "license": "MIT", - "dependencies": { - "string-width": "^4.2.0" - }, - "engines": { - "node": "10.* || >= 12.*" - }, - "optionalDependencies": { - "@colors/colors": "1.5.0" - } - }, - "node_modules/cli-table3/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/cli-table3/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/clsx": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", - "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/collapse-white-space": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz", - "integrity": "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/colord": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", - "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", - "license": "MIT" - }, - "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "license": "MIT" - }, - "node_modules/combine-promises": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/combine-promises/-/combine-promises-1.2.0.tgz", - "integrity": "sha512-VcQB1ziGD0NXrhKxiwyNbCDmRzs/OShMs2GqW2DlU2A/Sd0nQxE1oWDAE5O0ygSx5mgQOn9eIFh7yKPgFRVkPQ==", - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/comma-separated-tokens": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", - "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/commander": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", - "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/common-path-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", - "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", - "license": "ISC" - }, - "node_modules/compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "license": "MIT", - "dependencies": { - "mime-db": ">= 1.43.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/compressible/node_modules/mime-db": { - "version": "1.54.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", - "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/compression": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.0.tgz", - "integrity": "sha512-k6WLKfunuqCYD3t6AsuPGvQWaKwuLLh2/xHNcX4qE+vIfDNXpSqnrhwA7O53R7WVQUnt8dVAIW+YHr7xTgOgGA==", - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "compressible": "~2.0.18", - "debug": "2.6.9", - "negotiator": "~0.6.4", - "on-headers": "~1.0.2", - "safe-buffer": "5.2.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/compression/node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/compression/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/compression/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "license": "MIT" - }, - "node_modules/config-chain": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", - "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", - "license": "MIT", - "dependencies": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" - } - }, - "node_modules/config-chain/node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "license": "ISC" - }, - "node_modules/configstore": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-6.0.0.tgz", - "integrity": "sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA==", - "license": "BSD-2-Clause", - "dependencies": { - "dot-prop": "^6.0.1", - "graceful-fs": "^4.2.6", - "unique-string": "^3.0.0", - "write-file-atomic": "^3.0.3", - "xdg-basedir": "^5.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/yeoman/configstore?sponsor=1" - } - }, - "node_modules/connect-history-api-fallback": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", - "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", - "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/consola": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", - "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", - "license": "MIT", - "engines": { - "node": "^14.18.0 || >=16.10.0" - } - }, - "node_modules/content-disposition": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", - "integrity": "sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "license": "MIT" - }, - "node_modules/cookie": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", - "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", - "license": "MIT" - }, - "node_modules/copy-text-to-clipboard": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/copy-text-to-clipboard/-/copy-text-to-clipboard-3.2.0.tgz", - "integrity": "sha512-RnJFp1XR/LOBDckxTib5Qjr/PMfkatD0MUCQgdpqS8MdKiNUzBjAQBEN6oUy+jW7LI93BBG3DtMB2KOOKpGs2Q==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/copy-webpack-plugin": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz", - "integrity": "sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==", - "license": "MIT", - "dependencies": { - "fast-glob": "^3.2.11", - "glob-parent": "^6.0.1", - "globby": "^13.1.1", - "normalize-path": "^3.0.0", - "schema-utils": "^4.0.0", - "serialize-javascript": "^6.0.0" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - } - }, - "node_modules/copy-webpack-plugin/node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/copy-webpack-plugin/node_modules/globby": { - "version": "13.2.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", - "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", - "license": "MIT", - "dependencies": { - "dir-glob": "^3.0.1", - "fast-glob": "^3.3.0", - "ignore": "^5.2.4", - "merge2": "^1.4.1", - "slash": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/copy-webpack-plugin/node_modules/slash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", - "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/core-js": { - "version": "3.43.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.43.0.tgz", - "integrity": "sha512-N6wEbTTZSYOY2rYAn85CuvWWkCK6QweMn7/4Nr3w+gDBeBhk/x4EJeY6FPo4QzDoJZxVTv8U7CMvgWk6pOHHqA==", - "hasInstallScript": true, - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-js-compat": { - "version": "3.43.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.43.0.tgz", - "integrity": "sha512-2GML2ZsCc5LR7hZYz4AXmjQw8zuy2T//2QntwdnpuYI7jteT6GVYJL7F6C2C57R7gSYrcqVW3lAALefdbhBLDA==", - "license": "MIT", - "dependencies": { - "browserslist": "^4.25.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-js-pure": { - "version": "3.43.0", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.43.0.tgz", - "integrity": "sha512-i/AgxU2+A+BbJdMxh3v7/vxi2SbFqxiFmg6VsDwYB4jkucrd1BZNA9a9gphC0fYMG5IBSgQcbQnk865VCLe7xA==", - "hasInstallScript": true, - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "license": "MIT" - }, - "node_modules/cosmiconfig": { - "version": "8.3.6", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", - "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", - "license": "MIT", - "dependencies": { - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0", - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/d-fischer" - }, - "peerDependencies": { - "typescript": ">=4.9.5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/crypto-random-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", - "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", - "license": "MIT", - "dependencies": { - "type-fest": "^1.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/crypto-random-string/node_modules/type-fest": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", - "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/css-blank-pseudo": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-7.0.1.tgz", - "integrity": "sha512-jf+twWGDf6LDoXDUode+nc7ZlrqfaNphrBIBrcmeP3D8yw1uPaix1gCC8LUQUGQ6CycuK2opkbFFWFuq/a94ag==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "postcss-selector-parser": "^7.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/css-blank-pseudo/node_modules/postcss-selector-parser": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", - "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/css-declaration-sorter": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.2.0.tgz", - "integrity": "sha512-h70rUM+3PNFuaBDTLe8wF/cdWu+dOZmb7pJt8Z2sedYbAcQVQV/tEchueg3GWxwqS0cxtbxmaHEdkNACqcvsow==", - "license": "ISC", - "engines": { - "node": "^14 || ^16 || >=18" - }, - "peerDependencies": { - "postcss": "^8.0.9" - } - }, - "node_modules/css-has-pseudo": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-7.0.2.tgz", - "integrity": "sha512-nzol/h+E0bId46Kn2dQH5VElaknX2Sr0hFuB/1EomdC7j+OISt2ZzK7EHX9DZDY53WbIVAR7FYKSO2XnSf07MQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/selector-specificity": "^5.0.0", - "postcss-selector-parser": "^7.0.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/css-has-pseudo/node_modules/@csstools/selector-specificity": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", - "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss-selector-parser": "^7.0.0" - } - }, - "node_modules/css-has-pseudo/node_modules/postcss-selector-parser": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", - "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/css-loader": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.11.0.tgz", - "integrity": "sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g==", - "license": "MIT", - "dependencies": { - "icss-utils": "^5.1.0", - "postcss": "^8.4.33", - "postcss-modules-extract-imports": "^3.1.0", - "postcss-modules-local-by-default": "^4.0.5", - "postcss-modules-scope": "^3.2.0", - "postcss-modules-values": "^4.0.0", - "postcss-value-parser": "^4.2.0", - "semver": "^7.5.4" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "@rspack/core": "0.x || 1.x", - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "@rspack/core": { - "optional": true - }, - "webpack": { - "optional": true - } - } - }, - "node_modules/css-minimizer-webpack-plugin": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-5.0.1.tgz", - "integrity": "sha512-3caImjKFQkS+ws1TGcFn0V1HyDJFq1Euy589JlD6/3rV2kj+w7r5G9WDMgSHvpvXHNZ2calVypZWuEDQd9wfLg==", - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.18", - "cssnano": "^6.0.1", - "jest-worker": "^29.4.3", - "postcss": "^8.4.24", - "schema-utils": "^4.0.1", - "serialize-javascript": "^6.0.1" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "@parcel/css": { - "optional": true - }, - "@swc/css": { - "optional": true - }, - "clean-css": { - "optional": true - }, - "csso": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "lightningcss": { - "optional": true - } - } - }, - "node_modules/css-prefers-color-scheme": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-10.0.0.tgz", - "integrity": "sha512-VCtXZAWivRglTZditUfB4StnsWr6YVZ2PRtuxQLKTNRdtAf8tpzaVPE9zXIF3VaSc7O70iK/j1+NXxyQCqdPjQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/css-select": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", - "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.1.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css-tree": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", - "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", - "license": "MIT", - "dependencies": { - "mdn-data": "2.0.30", - "source-map-js": "^1.0.1" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" - } - }, - "node_modules/css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", - "license": "BSD-2-Clause", - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/cssdb": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-8.3.1.tgz", - "integrity": "sha512-XnDRQMXucLueX92yDe0LPKupXetWoFOgawr4O4X41l5TltgK2NVbJJVDnnOywDYfW1sTJ28AcXGKOqdRKwCcmQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - } - ], - "license": "MIT-0" - }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "license": "MIT", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cssnano": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-6.1.2.tgz", - "integrity": "sha512-rYk5UeX7VAM/u0lNqewCdasdtPK81CgX8wJFLEIXHbV2oldWRgJAsZrdhRXkV1NJzA2g850KiFm9mMU2HxNxMA==", - "license": "MIT", - "dependencies": { - "cssnano-preset-default": "^6.1.2", - "lilconfig": "^3.1.1" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/cssnano" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/cssnano-preset-advanced": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/cssnano-preset-advanced/-/cssnano-preset-advanced-6.1.2.tgz", - "integrity": "sha512-Nhao7eD8ph2DoHolEzQs5CfRpiEP0xa1HBdnFZ82kvqdmbwVBUr2r1QuQ4t1pi+D1ZpqpcO4T+wy/7RxzJ/WPQ==", - "license": "MIT", - "dependencies": { - "autoprefixer": "^10.4.19", - "browserslist": "^4.23.0", - "cssnano-preset-default": "^6.1.2", - "postcss-discard-unused": "^6.0.5", - "postcss-merge-idents": "^6.0.3", - "postcss-reduce-idents": "^6.0.3", - "postcss-zindex": "^6.0.2" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/cssnano-preset-default": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-6.1.2.tgz", - "integrity": "sha512-1C0C+eNaeN8OcHQa193aRgYexyJtU8XwbdieEjClw+J9d94E41LwT6ivKH0WT+fYwYWB0Zp3I3IZ7tI/BbUbrg==", - "license": "MIT", - "dependencies": { - "browserslist": "^4.23.0", - "css-declaration-sorter": "^7.2.0", - "cssnano-utils": "^4.0.2", - "postcss-calc": "^9.0.1", - "postcss-colormin": "^6.1.0", - "postcss-convert-values": "^6.1.0", - "postcss-discard-comments": "^6.0.2", - "postcss-discard-duplicates": "^6.0.3", - "postcss-discard-empty": "^6.0.3", - "postcss-discard-overridden": "^6.0.2", - "postcss-merge-longhand": "^6.0.5", - "postcss-merge-rules": "^6.1.1", - "postcss-minify-font-values": "^6.1.0", - "postcss-minify-gradients": "^6.0.3", - "postcss-minify-params": "^6.1.0", - "postcss-minify-selectors": "^6.0.4", - "postcss-normalize-charset": "^6.0.2", - "postcss-normalize-display-values": "^6.0.2", - "postcss-normalize-positions": "^6.0.2", - "postcss-normalize-repeat-style": "^6.0.2", - "postcss-normalize-string": "^6.0.2", - "postcss-normalize-timing-functions": "^6.0.2", - "postcss-normalize-unicode": "^6.1.0", - "postcss-normalize-url": "^6.0.2", - "postcss-normalize-whitespace": "^6.0.2", - "postcss-ordered-values": "^6.0.2", - "postcss-reduce-initial": "^6.1.0", - "postcss-reduce-transforms": "^6.0.2", - "postcss-svgo": "^6.0.3", - "postcss-unique-selectors": "^6.0.4" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/cssnano-utils": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-4.0.2.tgz", - "integrity": "sha512-ZR1jHg+wZ8o4c3zqf1SIUSTIvm/9mU343FMR6Obe/unskbvpGhZOo1J6d/r8D1pzkRQYuwbcH3hToOuoA2G7oQ==", - "license": "MIT", - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/csso": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", - "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", - "license": "MIT", - "dependencies": { - "css-tree": "~2.2.0" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/csso/node_modules/css-tree": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", - "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", - "license": "MIT", - "dependencies": { - "mdn-data": "2.0.28", - "source-map-js": "^1.0.1" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/csso/node_modules/mdn-data": { - "version": "2.0.28", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", - "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", - "license": "CC0-1.0" - }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "license": "MIT" - }, - "node_modules/debounce": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", - "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==", - "license": "MIT" - }, - "node_modules/debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decode-named-character-reference": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.2.0.tgz", - "integrity": "sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==", - "license": "MIT", - "dependencies": { - "character-entities": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "license": "MIT", - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decompress-response/node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "license": "MIT", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/default-gateway": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", - "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", - "license": "BSD-2-Clause", - "dependencies": { - "execa": "^5.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "license": "MIT", - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "license": "MIT", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", - "license": "MIT" - }, - "node_modules/detect-port": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.6.1.tgz", - "integrity": "sha512-CmnVc+Hek2egPx1PeTFVta2W78xy2K/9Rkf6cC4T59S50tVnzKj+tnx5mmx5lwvCkujZ4uRrpRSuV+IVs3f90Q==", - "license": "MIT", - "dependencies": { - "address": "^1.0.1", - "debug": "4" - }, - "bin": { - "detect": "bin/detect-port.js", - "detect-port": "bin/detect-port.js" - }, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/devlop": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", - "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", - "license": "MIT", - "dependencies": { - "dequal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "license": "MIT", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/dns-packet": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", - "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", - "license": "MIT", - "dependencies": { - "@leichtgewicht/ip-codec": "^2.0.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/dom-converter": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", - "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", - "license": "MIT", - "dependencies": { - "utila": "~0.4" - } - }, - "node_modules/dom-serializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", - "license": "MIT", - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "entities": "^4.2.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "BSD-2-Clause" - }, - "node_modules/domhandler": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "license": "BSD-2-Clause", - "dependencies": { - "domelementtype": "^2.3.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/domutils": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", - "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", - "license": "BSD-2-Clause", - "dependencies": { - "dom-serializer": "^2.0.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/dot-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", - "license": "MIT", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/dot-prop": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", - "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", - "license": "MIT", - "dependencies": { - "is-obj": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/dot-prop/node_modules/is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/dunder-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", - "license": "MIT" - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "license": "MIT" - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "license": "MIT" - }, - "node_modules/electron-to-chromium": { - "version": "1.5.173", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.173.tgz", - "integrity": "sha512-2bFhXP2zqSfQHugjqJIDFVwa+qIxyNApenmXTp9EjaKtdPrES5Qcn9/aSFy/NaP2E+fWG/zxKu/LBvY36p5VNQ==", - "license": "ISC" - }, - "node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "license": "MIT" - }, - "node_modules/emojilib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", - "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==", - "license": "MIT" - }, - "node_modules/emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/emoticon": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/emoticon/-/emoticon-4.1.0.tgz", - "integrity": "sha512-VWZfnxqwNcc51hIy/sbOdEem6D+cVtpPzEEtVAFdaas30+1dgkyaOQ4sQ6Bp0tOMqWO1v+HQfYaoodOkdhK6SQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/enhanced-resolve": { - "version": "5.18.2", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.2.tgz", - "integrity": "sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es-define-property": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-module-lexer": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", - "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", - "license": "MIT" - }, - "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/esast-util-from-estree": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/esast-util-from-estree/-/esast-util-from-estree-2.0.0.tgz", - "integrity": "sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "devlop": "^1.0.0", - "estree-util-visit": "^2.0.0", - "unist-util-position-from-estree": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/esast-util-from-js": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/esast-util-from-js/-/esast-util-from-js-2.0.1.tgz", - "integrity": "sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "acorn": "^8.0.0", - "esast-util-from-estree": "^2.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-goat": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-4.0.0.tgz", - "integrity": "sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "license": "MIT" - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "license": "BSD-2-Clause", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estree-util-attach-comments": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz", - "integrity": "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-build-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-3.0.1.tgz", - "integrity": "sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "devlop": "^1.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "estree-walker": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-is-identifier-name": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", - "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-scope": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/estree-util-scope/-/estree-util-scope-1.0.0.tgz", - "integrity": "sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "devlop": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-to-js": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-2.0.0.tgz", - "integrity": "sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "astring": "^1.8.0", - "source-map": "^0.7.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-value-to-estree": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/estree-util-value-to-estree/-/estree-util-value-to-estree-3.4.0.tgz", - "integrity": "sha512-Zlp+gxis+gCfK12d3Srl2PdX2ybsEA8ZYy6vQGVQTNNYLEGRQQ56XB64bjemN8kxIKXP1nC9ip4Z+ILy9LGzvQ==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/remcohaszing" - } - }, - "node_modules/estree-util-visit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-2.0.0.tgz", - "integrity": "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eta": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/eta/-/eta-2.2.0.tgz", - "integrity": "sha512-UVQ72Rqjy/ZKQalzV5dCCJP80GrmPrMxh6NlNf+erV6ObL0ZFkhCstWRawS85z3smdr3d2wXPsZEY7rDPfGd2g==", - "license": "MIT", - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "url": "https://github.com/eta-dev/eta?sponsor=1" - } - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/eval": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/eval/-/eval-0.1.8.tgz", - "integrity": "sha512-EzV94NYKoO09GLXGjXj9JIlXijVck4ONSr5wiCWDvhsvj5jxSrzTmRU/9C1DyB6uToszLs8aifA6NQ7lEQdvFw==", - "dependencies": { - "@types/node": "*", - "require-like": ">= 0.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "license": "MIT" - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "license": "MIT", - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/express": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", - "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", - "license": "MIT", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.3", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.7.1", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.3.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.3", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.12", - "proxy-addr": "~2.0.7", - "qs": "6.13.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.19.0", - "serve-static": "1.16.2", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/express/node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "license": "MIT", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/express/node_modules/path-to-regexp": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", - "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", - "license": "MIT" - }, - "node_modules/express/node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "license": "MIT" - }, - "node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "license": "MIT", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "license": "MIT" - }, - "node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "license": "MIT" - }, - "node_modules/fast-uri": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", - "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/fastq": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", - "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fault": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", - "integrity": "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==", - "license": "MIT", - "dependencies": { - "format": "^0.2.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/faye-websocket": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", - "license": "Apache-2.0", - "dependencies": { - "websocket-driver": ">=0.5.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/feed": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/feed/-/feed-4.2.2.tgz", - "integrity": "sha512-u5/sxGfiMfZNtJ3OvQpXcvotFpYkL0n9u9mM2vkui2nGo8b4wvDkJ8gAkYqbA8QpGyFCv3RK0Z+Iv+9veCS9bQ==", - "license": "MIT", - "dependencies": { - "xml-js": "^1.6.11" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^1.0.5" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/figures/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/file-loader": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", - "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", - "license": "MIT", - "dependencies": { - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/file-loader/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/file-loader/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "license": "MIT", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/file-loader/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "license": "MIT" - }, - "node_modules/file-loader/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/finalhandler": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", - "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", - "license": "MIT", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/find-cache-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", - "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", - "license": "MIT", - "dependencies": { - "common-path-prefix": "^3.0.0", - "pkg-dir": "^7.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/find-up": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", - "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", - "license": "MIT", - "dependencies": { - "locate-path": "^7.1.0", - "path-exists": "^5.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "license": "BSD-3-Clause", - "bin": { - "flat": "cli.js" - } - }, - "node_modules/follow-redirects": { - "version": "1.15.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", - "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "license": "MIT", - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/form-data-encoder": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", - "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==", - "license": "MIT", - "engines": { - "node": ">= 14.17" - } - }, - "node_modules/format": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", - "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==", - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fraction.js": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", - "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", - "license": "MIT", - "engines": { - "node": "*" - }, - "funding": { - "type": "patreon", - "url": "https://github.com/sponsors/rawify" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fs-extra": { - "version": "11.3.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", - "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=14.14" - } - }, - "node_modules/fs-monkey": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.6.tgz", - "integrity": "sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==", - "license": "Unlicense" - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "license": "ISC" - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-intrinsic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-own-enumerable-property-symbols": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", - "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", - "license": "ISC" - }, - "node_modules/get-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/github-slugger": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.5.0.tgz", - "integrity": "sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==", - "license": "ISC" - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "license": "BSD-2-Clause" - }, - "node_modules/global-dirs": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", - "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", - "license": "MIT", - "dependencies": { - "ini": "2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "license": "MIT", - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/got": { - "version": "12.6.1", - "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz", - "integrity": "sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==", - "license": "MIT", - "dependencies": { - "@sindresorhus/is": "^5.2.0", - "@szmarczak/http-timer": "^5.0.1", - "cacheable-lookup": "^7.0.0", - "cacheable-request": "^10.2.8", - "decompress-response": "^6.0.0", - "form-data-encoder": "^2.1.2", - "get-stream": "^6.0.1", - "http2-wrapper": "^2.1.10", - "lowercase-keys": "^3.0.0", - "p-cancelable": "^3.0.0", - "responselike": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sindresorhus/got?sponsor=1" - } - }, - "node_modules/got/node_modules/@sindresorhus/is": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", - "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==", - "license": "MIT", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "license": "ISC" - }, - "node_modules/gray-matter": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", - "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", - "license": "MIT", - "dependencies": { - "js-yaml": "^3.13.1", - "kind-of": "^6.0.2", - "section-matter": "^1.0.0", - "strip-bom-string": "^1.0.0" - }, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/gray-matter/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/gray-matter/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/gzip-size": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", - "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", - "license": "MIT", - "dependencies": { - "duplexer": "^0.1.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/handle-thing": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", - "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", - "license": "MIT" - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-yarn": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-3.0.0.tgz", - "integrity": "sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA==", - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/hast-util-from-parse5": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.3.tgz", - "integrity": "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "devlop": "^1.0.0", - "hastscript": "^9.0.0", - "property-information": "^7.0.0", - "vfile": "^6.0.0", - "vfile-location": "^5.0.0", - "web-namespaces": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-parse-selector": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", - "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-raw": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.1.0.tgz", - "integrity": "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "@ungap/structured-clone": "^1.0.0", - "hast-util-from-parse5": "^8.0.0", - "hast-util-to-parse5": "^8.0.0", - "html-void-elements": "^3.0.0", - "mdast-util-to-hast": "^13.0.0", - "parse5": "^7.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-estree": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-3.1.3.tgz", - "integrity": "sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "devlop": "^1.0.0", - "estree-util-attach-comments": "^3.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "hast-util-whitespace": "^3.0.0", - "mdast-util-mdx-expression": "^2.0.0", - "mdast-util-mdx-jsx": "^3.0.0", - "mdast-util-mdxjs-esm": "^2.0.0", - "property-information": "^7.0.0", - "space-separated-tokens": "^2.0.0", - "style-to-js": "^1.0.0", - "unist-util-position": "^5.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-jsx-runtime": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz", - "integrity": "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "devlop": "^1.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "hast-util-whitespace": "^3.0.0", - "mdast-util-mdx-expression": "^2.0.0", - "mdast-util-mdx-jsx": "^3.0.0", - "mdast-util-mdxjs-esm": "^2.0.0", - "property-information": "^7.0.0", - "space-separated-tokens": "^2.0.0", - "style-to-js": "^1.0.0", - "unist-util-position": "^5.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-parse5": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.0.tgz", - "integrity": "sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "devlop": "^1.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-parse5/node_modules/property-information": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz", - "integrity": "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/hast-util-whitespace": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", - "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hastscript": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-9.0.1.tgz", - "integrity": "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-parse-selector": "^4.0.0", - "property-information": "^7.0.0", - "space-separated-tokens": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "license": "MIT", - "bin": { - "he": "bin/he" - } - }, - "node_modules/history": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", - "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.1.2", - "loose-envify": "^1.2.0", - "resolve-pathname": "^3.0.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0", - "value-equal": "^1.0.1" - } - }, - "node_modules/hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "license": "BSD-3-Clause", - "dependencies": { - "react-is": "^16.7.0" - } - }, - "node_modules/hpack.js": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" - } - }, - "node_modules/hpack.js/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "license": "MIT" - }, - "node_modules/hpack.js/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/hpack.js/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "license": "MIT" - }, - "node_modules/hpack.js/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/html-entities": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.6.0.tgz", - "integrity": "sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/mdevils" - }, - { - "type": "patreon", - "url": "https://patreon.com/mdevils" - } - ], - "license": "MIT" - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "license": "MIT" - }, - "node_modules/html-minifier-terser": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-7.2.0.tgz", - "integrity": "sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==", - "license": "MIT", - "dependencies": { - "camel-case": "^4.1.2", - "clean-css": "~5.3.2", - "commander": "^10.0.0", - "entities": "^4.4.0", - "param-case": "^3.0.4", - "relateurl": "^0.2.7", - "terser": "^5.15.1" - }, - "bin": { - "html-minifier-terser": "cli.js" - }, - "engines": { - "node": "^14.13.1 || >=16.0.0" - } - }, - "node_modules/html-minifier-terser/node_modules/commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", - "license": "MIT", - "engines": { - "node": ">=14" - } - }, - "node_modules/html-tags": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", - "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/html-webpack-plugin": { - "version": "5.6.3", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.3.tgz", - "integrity": "sha512-QSf1yjtSAsmf7rYBV7XX86uua4W/vkhIt0xNXKbsi2foEeW7vjJQz4bhnpL3xH+l1ryl1680uNv968Z+X6jSYg==", - "license": "MIT", - "dependencies": { - "@types/html-minifier-terser": "^6.0.0", - "html-minifier-terser": "^6.0.2", - "lodash": "^4.17.21", - "pretty-error": "^4.0.0", - "tapable": "^2.0.0" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/html-webpack-plugin" - }, - "peerDependencies": { - "@rspack/core": "0.x || 1.x", - "webpack": "^5.20.0" - }, - "peerDependenciesMeta": { - "@rspack/core": { - "optional": true - }, - "webpack": { - "optional": true - } - } - }, - "node_modules/html-webpack-plugin/node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "license": "MIT", - "engines": { - "node": ">= 12" - } - }, - "node_modules/html-webpack-plugin/node_modules/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", - "license": "MIT", - "dependencies": { - "camel-case": "^4.1.2", - "clean-css": "^5.2.2", - "commander": "^8.3.0", - "he": "^1.2.0", - "param-case": "^3.0.4", - "relateurl": "^0.2.7", - "terser": "^5.10.0" - }, - "bin": { - "html-minifier-terser": "cli.js" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/htmlparser2": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", - "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "MIT", - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "entities": "^4.4.0" - } - }, - "node_modules/http-cache-semantics": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", - "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", - "license": "BSD-2-Clause" - }, - "node_modules/http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", - "license": "MIT" - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "license": "MIT", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/http-parser-js": { - "version": "0.5.10", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz", - "integrity": "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==", - "license": "MIT" - }, - "node_modules/http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "license": "MIT", - "dependencies": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/http-proxy-middleware": { - "version": "2.0.9", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.9.tgz", - "integrity": "sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q==", - "license": "MIT", - "dependencies": { - "@types/http-proxy": "^1.17.8", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.1", - "is-plain-obj": "^3.0.0", - "micromatch": "^4.0.2" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "@types/express": "^4.17.13" - }, - "peerDependenciesMeta": { - "@types/express": { - "optional": true - } - } - }, - "node_modules/http-proxy-middleware/node_modules/is-plain-obj": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", - "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/http2-wrapper": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", - "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", - "license": "MIT", - "dependencies": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.2.0" - }, - "engines": { - "node": ">=10.19.0" - } - }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "license": "Apache-2.0", - "engines": { - "node": ">=10.17.0" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/icss-utils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", - "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "license": "ISC", - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/image-size": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/image-size/-/image-size-2.0.2.tgz", - "integrity": "sha512-IRqXKlaXwgSMAMtpNzZa1ZAe8m+Sa1770Dhk8VkSsP9LS+iHD62Zd8FQKs8fbPiagBE7BzoFX23cxFnwshpV6w==", - "license": "MIT", - "bin": { - "image-size": "bin/image-size.js" - }, - "engines": { - "node": ">=16.x" - } - }, - "node_modules/import-fresh": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-lazy": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", - "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/infima": { - "version": "0.2.0-alpha.45", - "resolved": "https://registry.npmjs.org/infima/-/infima-0.2.0-alpha.45.tgz", - "integrity": "sha512-uyH0zfr1erU1OohLk0fT4Rrb94AOhguWNOcD9uGrSpRvNB+6gZXUoJX5J0NtvzBO10YZ9PgvA4NFgt+fYg8ojw==", - "license": "MIT", - "engines": { - "node": ">=12" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC" - }, - "node_modules/ini": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", - "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/inline-style-parser": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.4.tgz", - "integrity": "sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==", - "license": "MIT" - }, - "node_modules/invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.0.0" - } - }, - "node_modules/ipaddr.js": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", - "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", - "license": "MIT", - "engines": { - "node": ">= 10" - } - }, - "node_modules/is-alphabetical": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", - "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-alphanumerical": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", - "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", - "license": "MIT", - "dependencies": { - "is-alphabetical": "^2.0.0", - "is-decimal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "license": "MIT" - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "license": "MIT", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-ci": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", - "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", - "license": "MIT", - "dependencies": { - "ci-info": "^3.2.0" - }, - "bin": { - "is-ci": "bin.js" - } - }, - "node_modules/is-core-module": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", - "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", - "license": "MIT", - "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-decimal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", - "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "license": "MIT", - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-hexadecimal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", - "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-installed-globally": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", - "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", - "license": "MIT", - "dependencies": { - "global-dirs": "^3.0.0", - "is-path-inside": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-npm": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-6.0.0.tgz", - "integrity": "sha512-JEjxbSmtPSt1c8XTkVrlujcXdKV1/tvuQ7GwKcAlyiVLeYFQ2VHat8xfrDJsIkhCdF/tZ7CiIR3sy141c6+gPQ==", - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-obj": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", - "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "license": "MIT", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "license": "MIT" - }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "license": "MIT", - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-yarn-global": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.4.1.tgz", - "integrity": "sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ==", - "license": "MIT", - "engines": { - "node": ">=12" - } - }, - "node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", - "license": "MIT" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "license": "ISC" - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/jest-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", - "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-worker": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", - "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "jest-util": "^29.7.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/jiti": { - "version": "1.21.7", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", - "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", - "license": "MIT", - "bin": { - "jiti": "bin/jiti.js" - } - }, - "node_modules/joi": { - "version": "17.13.3", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz", - "integrity": "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==", - "license": "BSD-3-Clause", - "dependencies": { - "@hapi/hoek": "^9.3.0", - "@hapi/topo": "^5.1.0", - "@sideway/address": "^4.1.5", - "@sideway/formula": "^3.0.1", - "@sideway/pinpoint": "^2.0.0" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "license": "MIT" - }, - "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==", - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsesc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "license": "MIT" - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "license": "MIT" - }, - "node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "license": "MIT" - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "license": "MIT", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "license": "MIT", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "license": "MIT", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/latest-version": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-7.0.0.tgz", - "integrity": "sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==", - "license": "MIT", - "dependencies": { - "package-json": "^8.1.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/launch-editor": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.10.0.tgz", - "integrity": "sha512-D7dBRJo/qcGX9xlvt/6wUYzQxjh5G1RvZPgPv8vi4KRU99DVQL/oW7tnVOCCTm2HGeo3C5HvGE5Yrh6UBoZ0vA==", - "license": "MIT", - "dependencies": { - "picocolors": "^1.0.0", - "shell-quote": "^1.8.1" - } - }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/lilconfig": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", - "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", - "license": "MIT", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antonk52" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "license": "MIT" - }, - "node_modules/loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", - "license": "MIT", - "engines": { - "node": ">=6.11.5" - } - }, - "node_modules/loader-utils": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", - "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", - "license": "MIT", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, - "node_modules/locate-path": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", - "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", - "license": "MIT", - "dependencies": { - "p-locate": "^6.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "license": "MIT" - }, - "node_modules/lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", - "license": "MIT" - }, - "node_modules/lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", - "license": "MIT" - }, - "node_modules/lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", - "license": "MIT" - }, - "node_modules/longest-streak": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", - "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "license": "MIT", - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "license": "MIT", - "dependencies": { - "tslib": "^2.0.3" - } - }, - "node_modules/lowercase-keys": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", - "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "license": "ISC", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/markdown-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-2.0.0.tgz", - "integrity": "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==", - "license": "MIT", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/markdown-table": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", - "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/math-intrinsics": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/mdast-util-directive": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.1.0.tgz", - "integrity": "sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "ccount": "^2.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "parse-entities": "^4.0.0", - "stringify-entities": "^4.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-find-and-replace": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", - "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "escape-string-regexp": "^5.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mdast-util-from-markdown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", - "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark": "^4.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-decode-string": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-from-markdown/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/mdast-util-frontmatter": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-2.0.1.tgz", - "integrity": "sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "escape-string-regexp": "^5.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "micromark-extension-frontmatter": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-frontmatter/node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mdast-util-gfm": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", - "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", - "license": "MIT", - "dependencies": { - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-gfm-autolink-literal": "^2.0.0", - "mdast-util-gfm-footnote": "^2.0.0", - "mdast-util-gfm-strikethrough": "^2.0.0", - "mdast-util-gfm-table": "^2.0.0", - "mdast-util-gfm-task-list-item": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-autolink-literal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", - "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "ccount": "^2.0.0", - "devlop": "^1.0.0", - "mdast-util-find-and-replace": "^3.0.0", - "micromark-util-character": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-character": { - "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==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/mdast-util-gfm-footnote": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", - "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.1.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-strikethrough": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", - "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-table": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", - "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "markdown-table": "^3.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-task-list-item": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", - "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz", - "integrity": "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==", - "license": "MIT", - "dependencies": { - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-mdx-expression": "^2.0.0", - "mdast-util-mdx-jsx": "^3.0.0", - "mdast-util-mdxjs-esm": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx-expression": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz", - "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx-jsx": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz", - "integrity": "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "ccount": "^2.0.0", - "devlop": "^1.1.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "parse-entities": "^4.0.0", - "stringify-entities": "^4.0.0", - "unist-util-stringify-position": "^4.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdxjs-esm": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", - "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-phrasing": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", - "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-hast": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", - "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "@ungap/structured-clone": "^1.0.0", - "devlop": "^1.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "trim-lines": "^3.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-markdown": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", - "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "longest-streak": "^3.0.0", - "mdast-util-phrasing": "^4.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-decode-string": "^2.0.0", - "unist-util-visit": "^5.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", - "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdn-data": { - "version": "2.0.30", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", - "license": "CC0-1.0" - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/memfs": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", - "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", - "license": "Unlicense", - "dependencies": { - "fs-monkey": "^1.0.4" - }, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", - "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "license": "MIT" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/micromark": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", - "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-core-commonmark": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", - "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-destination": "^2.0.0", - "micromark-factory-label": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-title": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-html-tag-name": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-core-commonmark/node_modules/micromark-factory-space": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-core-commonmark/node_modules/micromark-util-character": { - "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==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-core-commonmark/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-extension-directive": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-3.0.2.tgz", - "integrity": "sha512-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "parse-entities": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-directive/node_modules/micromark-factory-space": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-directive/node_modules/micromark-util-character": { - "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==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-directive/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-extension-frontmatter": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-2.0.0.tgz", - "integrity": "sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==", - "license": "MIT", - "dependencies": { - "fault": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-frontmatter/node_modules/micromark-util-character": { - "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==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-frontmatter/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-extension-gfm": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", - "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", - "license": "MIT", - "dependencies": { - "micromark-extension-gfm-autolink-literal": "^2.0.0", - "micromark-extension-gfm-footnote": "^2.0.0", - "micromark-extension-gfm-strikethrough": "^2.0.0", - "micromark-extension-gfm-table": "^2.0.0", - "micromark-extension-gfm-tagfilter": "^2.0.0", - "micromark-extension-gfm-task-list-item": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-autolink-literal": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", - "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-character": { - "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==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-extension-gfm-footnote": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", - "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-factory-space": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-character": { - "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==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-extension-gfm-strikethrough": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", - "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-strikethrough/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-extension-gfm-table": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", - "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-table/node_modules/micromark-factory-space": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-character": { - "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==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-extension-gfm-tagfilter": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", - "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", - "license": "MIT", - "dependencies": { - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-task-list-item": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", - "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-factory-space": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-character": { - "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==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-extension-mdx-expression": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.1.tgz", - "integrity": "sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-mdx-expression": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-events-to-acorn": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-mdx-expression/node_modules/micromark-factory-space": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-mdx-expression/node_modules/micromark-util-character": { - "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==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-mdx-expression/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-extension-mdx-jsx": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.2.tgz", - "integrity": "sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "micromark-factory-mdx-expression": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-events-to-acorn": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-factory-space": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-util-character": { - "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==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-extension-mdx-md": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-2.0.0.tgz", - "integrity": "sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==", - "license": "MIT", - "dependencies": { - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-mdxjs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-3.0.0.tgz", - "integrity": "sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==", - "license": "MIT", - "dependencies": { - "acorn": "^8.0.0", - "acorn-jsx": "^5.0.0", - "micromark-extension-mdx-expression": "^3.0.0", - "micromark-extension-mdx-jsx": "^3.0.0", - "micromark-extension-mdx-md": "^2.0.0", - "micromark-extension-mdxjs-esm": "^3.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-mdxjs-esm": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-3.0.0.tgz", - "integrity": "sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-events-to-acorn": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-position-from-estree": "^2.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-mdxjs-esm/node_modules/micromark-util-character": { - "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==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-mdxjs-esm/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-factory-destination": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", - "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-destination/node_modules/micromark-util-character": { - "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==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-destination/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-factory-label": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", - "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-label/node_modules/micromark-util-character": { - "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==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-label/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-factory-mdx-expression": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.3.tgz", - "integrity": "sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-events-to-acorn": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-position-from-estree": "^2.0.0", - "vfile-message": "^4.0.0" - } - }, - "node_modules/micromark-factory-mdx-expression/node_modules/micromark-factory-space": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-mdx-expression/node_modules/micromark-util-character": { - "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==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-mdx-expression/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-factory-space": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz", - "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/micromark-factory-space/node_modules/micromark-util-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", - "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-factory-title": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", - "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-title/node_modules/micromark-factory-space": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-title/node_modules/micromark-util-character": { - "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==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-title/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-factory-whitespace": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", - "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-whitespace/node_modules/micromark-factory-space": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-whitespace/node_modules/micromark-util-character": { - "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==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-whitespace/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-character": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", - "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/micromark-util-character/node_modules/micromark-util-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", - "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-chunked": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", - "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-chunked/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-classify-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", - "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-classify-character/node_modules/micromark-util-character": { - "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==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-classify-character/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-combine-extensions": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", - "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-chunked": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-numeric-character-reference": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", - "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-numeric-character-reference/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-decode-string": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", - "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-string/node_modules/micromark-util-character": { - "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==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-string/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-encode": { - "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==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-events-to-acorn": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.3.tgz", - "integrity": "sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "@types/unist": "^3.0.0", - "devlop": "^1.0.0", - "estree-util-visit": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "vfile-message": "^4.0.0" - } - }, - "node_modules/micromark-util-events-to-acorn/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-html-tag-name": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", - "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-normalize-identifier": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", - "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-normalize-identifier/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-resolve-all": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", - "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-sanitize-uri": { - "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==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-sanitize-uri/node_modules/micromark-util-character": { - "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==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-sanitize-uri/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-subtokenize": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", - "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-subtokenize/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-symbol": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", - "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", - "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark/node_modules/micromark-factory-space": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark/node_modules/micromark-util-character": { - "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==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark/node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "license": "MIT", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "license": "MIT", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.18", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", - "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", - "license": "MIT", - "dependencies": { - "mime-db": "~1.33.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/mimic-response": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", - "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mini-css-extract-plugin": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.2.tgz", - "integrity": "sha512-GJuACcS//jtq4kCtd5ii/M0SZf7OZRH+BxdqXZHaJfb8TJiVl+NgQRPwiYt2EuqeSkNydn/7vP+bcE27C5mb9w==", - "license": "MIT", - "dependencies": { - "schema-utils": "^4.0.0", - "tapable": "^2.2.1" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - } - }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "license": "ISC" - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/mrmime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", - "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/multicast-dns": { - "version": "7.2.5", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", - "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", - "license": "MIT", - "dependencies": { - "dns-packet": "^5.2.2", - "thunky": "^1.0.2" - }, - "bin": { - "multicast-dns": "cli.js" - } - }, - "node_modules/nanoid": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/negotiator": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", - "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "license": "MIT" - }, - "node_modules/no-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", - "license": "MIT", - "dependencies": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - }, - "node_modules/node-emoji": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.2.0.tgz", - "integrity": "sha512-Z3lTE9pLaJF47NyMhd4ww1yFTAP8YhYI8SleJiHzM46Fgpm5cnNzSl9XfzFNqbaz+VlJrIj3fXQ4DeN1Rjm6cw==", - "license": "MIT", - "dependencies": { - "@sindresorhus/is": "^4.6.0", - "char-regex": "^1.0.2", - "emojilib": "^2.4.0", - "skin-tone": "^2.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/node-forge": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", - "license": "(BSD-3-Clause OR GPL-2.0)", - "engines": { - "node": ">= 6.13.0" - } - }, - "node_modules/node-releases": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", - "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", - "license": "MIT" - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-url": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.2.tgz", - "integrity": "sha512-Ee/R3SyN4BuynXcnTaekmaVdbDAEiNrHqjQIA37mHU8G9pf7aaAD4ZX3XjBLo6rsdcxA/gtkcNYZLt30ACgynw==", - "license": "MIT", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "license": "MIT", - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nprogress": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz", - "integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==", - "license": "MIT" - }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, - "node_modules/null-loader": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/null-loader/-/null-loader-4.0.1.tgz", - "integrity": "sha512-pxqVbi4U6N26lq+LmgIbB5XATP0VdZKOG25DhHi8btMmJJefGArFyDg1yc4U3hWCJbMqSrw0qyrz1UQX+qYXqg==", - "license": "MIT", - "dependencies": { - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/null-loader/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/null-loader/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "license": "MIT", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/null-loader/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "license": "MIT" - }, - "node_modules/null-loader/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", - "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0", - "has-symbols": "^1.1.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/obuf": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", - "license": "MIT" - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "license": "MIT", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/open": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", - "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", - "license": "MIT", - "dependencies": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/opener": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", - "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", - "license": "(WTFPL OR MIT)", - "bin": { - "opener": "bin/opener-bin.js" - } - }, - "node_modules/p-cancelable": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", - "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", - "license": "MIT", - "engines": { - "node": ">=12.20" - } - }, - "node_modules/p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/p-limit": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", - "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", - "license": "MIT", - "dependencies": { - "yocto-queue": "^1.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", - "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", - "license": "MIT", - "dependencies": { - "p-limit": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "license": "MIT", - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-queue": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", - "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", - "license": "MIT", - "dependencies": { - "eventemitter3": "^4.0.4", - "p-timeout": "^3.2.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-retry": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", - "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", - "license": "MIT", - "dependencies": { - "@types/retry": "0.12.0", - "retry": "^0.13.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-timeout": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", - "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", - "license": "MIT", - "dependencies": { - "p-finally": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/package-json": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-8.1.1.tgz", - "integrity": "sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==", - "license": "MIT", - "dependencies": { - "got": "^12.1.0", - "registry-auth-token": "^5.0.1", - "registry-url": "^6.0.0", - "semver": "^7.3.7" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/param-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", - "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", - "license": "MIT", - "dependencies": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-entities": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", - "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", - "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.0", - "character-entities-legacy": "^3.0.0", - "character-reference-invalid": "^2.0.0", - "decode-named-character-reference": "^1.0.0", - "is-alphanumerical": "^2.0.0", - "is-decimal": "^2.0.0", - "is-hexadecimal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/parse-entities/node_modules/@types/unist": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", - "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", - "license": "MIT" - }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parse-numeric-range": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz", - "integrity": "sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==", - "license": "ISC" - }, - "node_modules/parse5": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", - "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", - "license": "MIT", - "dependencies": { - "entities": "^6.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parse5-htmlparser2-tree-adapter": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", - "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", - "license": "MIT", - "dependencies": { - "domhandler": "^5.0.3", - "parse5": "^7.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parse5/node_modules/entities": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", - "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/pascal-case": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", - "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", - "license": "MIT", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/path-exists": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", - "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", - "license": "(WTFPL OR MIT)" - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "license": "MIT" - }, - "node_modules/path-to-regexp": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", - "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==", - "license": "MIT", - "dependencies": { - "isarray": "0.0.1" - } - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pkg-dir": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", - "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", - "license": "MIT", - "dependencies": { - "find-up": "^6.3.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/postcss": { - "version": "8.5.6", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", - "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.11", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/postcss-attribute-case-insensitive": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-7.0.1.tgz", - "integrity": "sha512-Uai+SupNSqzlschRyNx3kbCTWgY/2hcwtHEI/ej2LJWc9JJ77qKgGptd8DHwY1mXtZ7Aoh4z4yxfwMBue9eNgw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "dependencies": { - "postcss-selector-parser": "^7.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-attribute-case-insensitive/node_modules/postcss-selector-parser": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", - "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-calc": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-9.0.1.tgz", - "integrity": "sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==", - "license": "MIT", - "dependencies": { - "postcss-selector-parser": "^6.0.11", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.2.2" - } - }, - "node_modules/postcss-clamp": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-clamp/-/postcss-clamp-4.1.0.tgz", - "integrity": "sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": ">=7.6.0" - }, - "peerDependencies": { - "postcss": "^8.4.6" - } - }, - "node_modules/postcss-color-functional-notation": { - "version": "7.0.10", - "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-7.0.10.tgz", - "integrity": "sha512-k9qX+aXHBiLTRrWoCJuUFI6F1iF6QJQUXNVWJVSbqZgj57jDhBlOvD8gNUGl35tgqDivbGLhZeW3Ongz4feuKA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/css-color-parser": "^3.0.10", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4", - "@csstools/postcss-progressive-custom-properties": "^4.1.0", - "@csstools/utilities": "^2.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-color-hex-alpha": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-10.0.0.tgz", - "integrity": "sha512-1kervM2cnlgPs2a8Vt/Qbe5cQ++N7rkYo/2rz2BkqJZIHQwaVuJgQH38REHrAi4uM0b1fqxMkWYmese94iMp3w==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "dependencies": { - "@csstools/utilities": "^2.0.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-color-rebeccapurple": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-10.0.0.tgz", - "integrity": "sha512-JFta737jSP+hdAIEhk1Vs0q0YF5P8fFcj+09pweS8ktuGuZ8pPlykHsk6mPxZ8awDl4TrcxUqJo9l1IhVr/OjQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/utilities": "^2.0.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-colormin": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-6.1.0.tgz", - "integrity": "sha512-x9yX7DOxeMAR+BgGVnNSAxmAj98NX/YxEMNFP+SDCEeNLb2r3i6Hh1ksMsnW8Ub5SLCpbescQqn9YEbE9554Sw==", - "license": "MIT", - "dependencies": { - "browserslist": "^4.23.0", - "caniuse-api": "^3.0.0", - "colord": "^2.9.3", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-convert-values": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-6.1.0.tgz", - "integrity": "sha512-zx8IwP/ts9WvUM6NkVSkiU902QZL1bwPhaVaLynPtCsOTqp+ZKbNi+s6XJg3rfqpKGA/oc7Oxk5t8pOQJcwl/w==", - "license": "MIT", - "dependencies": { - "browserslist": "^4.23.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-custom-media": { - "version": "11.0.6", - "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-11.0.6.tgz", - "integrity": "sha512-C4lD4b7mUIw+RZhtY7qUbf4eADmb7Ey8BFA2px9jUbwg7pjTZDl4KY4bvlUV+/vXQvzQRfiGEVJyAbtOsCMInw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "dependencies": { - "@csstools/cascade-layer-name-parser": "^2.0.5", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4", - "@csstools/media-query-list-parser": "^4.0.3" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-custom-properties": { - "version": "14.0.6", - "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-14.0.6.tgz", - "integrity": "sha512-fTYSp3xuk4BUeVhxCSJdIPhDLpJfNakZKoiTDx7yRGCdlZrSJR7mWKVOBS4sBF+5poPQFMj2YdXx1VHItBGihQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "dependencies": { - "@csstools/cascade-layer-name-parser": "^2.0.5", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4", - "@csstools/utilities": "^2.0.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-custom-selectors": { - "version": "8.0.5", - "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-8.0.5.tgz", - "integrity": "sha512-9PGmckHQswiB2usSO6XMSswO2yFWVoCAuih1yl9FVcwkscLjRKjwsjM3t+NIWpSU2Jx3eOiK2+t4vVTQaoCHHg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "dependencies": { - "@csstools/cascade-layer-name-parser": "^2.0.5", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4", - "postcss-selector-parser": "^7.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-custom-selectors/node_modules/postcss-selector-parser": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", - "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-dir-pseudo-class": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-9.0.1.tgz", - "integrity": "sha512-tRBEK0MHYvcMUrAuYMEOa0zg9APqirBcgzi6P21OhxtJyJADo/SWBwY1CAwEohQ/6HDaa9jCjLRG7K3PVQYHEA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "postcss-selector-parser": "^7.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-dir-pseudo-class/node_modules/postcss-selector-parser": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", - "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-discard-comments": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-6.0.2.tgz", - "integrity": "sha512-65w/uIqhSBBfQmYnG92FO1mWZjJ4GL5b8atm5Yw2UgrwD7HiNiSSNwJor1eCFGzUgYnN/iIknhNRVqjrrpuglw==", - "license": "MIT", - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-discard-duplicates": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-6.0.3.tgz", - "integrity": "sha512-+JA0DCvc5XvFAxwx6f/e68gQu/7Z9ud584VLmcgto28eB8FqSFZwtrLwB5Kcp70eIoWP/HXqz4wpo8rD8gpsTw==", - "license": "MIT", - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-discard-empty": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-6.0.3.tgz", - "integrity": "sha512-znyno9cHKQsK6PtxL5D19Fj9uwSzC2mB74cpT66fhgOadEUPyXFkbgwm5tvc3bt3NAy8ltE5MrghxovZRVnOjQ==", - "license": "MIT", - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-discard-overridden": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-6.0.2.tgz", - "integrity": "sha512-j87xzI4LUggC5zND7KdjsI25APtyMuynXZSujByMaav2roV6OZX+8AaCUcZSWqckZpjAjRyFDdpqybgjFO0HJQ==", - "license": "MIT", - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-discard-unused": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-6.0.5.tgz", - "integrity": "sha512-wHalBlRHkaNnNwfC8z+ppX57VhvS+HWgjW508esjdaEYr3Mx7Gnn2xA4R/CKf5+Z9S5qsqC+Uzh4ueENWwCVUA==", - "license": "MIT", - "dependencies": { - "postcss-selector-parser": "^6.0.16" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-double-position-gradients": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-6.0.2.tgz", - "integrity": "sha512-7qTqnL7nfLRyJK/AHSVrrXOuvDDzettC+wGoienURV8v2svNbu6zJC52ruZtHaO6mfcagFmuTGFdzRsJKB3k5Q==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/postcss-progressive-custom-properties": "^4.1.0", - "@csstools/utilities": "^2.0.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-focus-visible": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-10.0.1.tgz", - "integrity": "sha512-U58wyjS/I1GZgjRok33aE8juW9qQgQUNwTSdxQGuShHzwuYdcklnvK/+qOWX1Q9kr7ysbraQ6ht6r+udansalA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "postcss-selector-parser": "^7.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-focus-visible/node_modules/postcss-selector-parser": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", - "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-focus-within": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-9.0.1.tgz", - "integrity": "sha512-fzNUyS1yOYa7mOjpci/bR+u+ESvdar6hk8XNK/TRR0fiGTp2QT5N+ducP0n3rfH/m9I7H/EQU6lsa2BrgxkEjw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "postcss-selector-parser": "^7.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-focus-within/node_modules/postcss-selector-parser": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", - "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-font-variant": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz", - "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==", - "license": "MIT", - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-gap-properties": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-6.0.0.tgz", - "integrity": "sha512-Om0WPjEwiM9Ru+VhfEDPZJAKWUd0mV1HmNXqp2C29z80aQ2uP9UVhLc7e3aYMIor/S5cVhoPgYQ7RtfeZpYTRw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-image-set-function": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-7.0.0.tgz", - "integrity": "sha512-QL7W7QNlZuzOwBTeXEmbVckNt1FSmhQtbMRvGGqqU4Nf4xk6KUEQhAoWuMzwbSv5jxiRiSZ5Tv7eiDB9U87znA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/utilities": "^2.0.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-lab-function": { - "version": "7.0.10", - "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-7.0.10.tgz", - "integrity": "sha512-tqs6TCEv9tC1Riq6fOzHuHcZyhg4k3gIAMB8GGY/zA1ssGdm6puHMVE7t75aOSoFg7UD2wyrFFhbldiCMyyFTQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/css-color-parser": "^3.0.10", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4", - "@csstools/postcss-progressive-custom-properties": "^4.1.0", - "@csstools/utilities": "^2.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-loader": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.3.4.tgz", - "integrity": "sha512-iW5WTTBSC5BfsBJ9daFMPVrLT36MrNiC6fqOZTTaHjBNX6Pfd5p+hSBqe/fEeNd7pc13QiAyGt7VdGMw4eRC4A==", - "license": "MIT", - "dependencies": { - "cosmiconfig": "^8.3.5", - "jiti": "^1.20.0", - "semver": "^7.5.4" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "postcss": "^7.0.0 || ^8.0.1", - "webpack": "^5.0.0" - } - }, - "node_modules/postcss-logical": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-8.1.0.tgz", - "integrity": "sha512-pL1hXFQ2fEXNKiNiAgtfA005T9FBxky5zkX6s4GZM2D8RkVgRqz3f4g1JUoq925zXv495qk8UNldDwh8uGEDoA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-merge-idents": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-6.0.3.tgz", - "integrity": "sha512-1oIoAsODUs6IHQZkLQGO15uGEbK3EAl5wi9SS8hs45VgsxQfMnxvt+L+zIr7ifZFIH14cfAeVe2uCTa+SPRa3g==", - "license": "MIT", - "dependencies": { - "cssnano-utils": "^4.0.2", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-merge-longhand": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-6.0.5.tgz", - "integrity": "sha512-5LOiordeTfi64QhICp07nzzuTDjNSO8g5Ksdibt44d+uvIIAE1oZdRn8y/W5ZtYgRH/lnLDlvi9F8btZcVzu3w==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0", - "stylehacks": "^6.1.1" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-merge-rules": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-6.1.1.tgz", - "integrity": "sha512-KOdWF0gju31AQPZiD+2Ar9Qjowz1LTChSjFFbS+e2sFgc4uHOp3ZvVX4sNeTlk0w2O31ecFGgrFzhO0RSWbWwQ==", - "license": "MIT", - "dependencies": { - "browserslist": "^4.23.0", - "caniuse-api": "^3.0.0", - "cssnano-utils": "^4.0.2", - "postcss-selector-parser": "^6.0.16" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-minify-font-values": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-6.1.0.tgz", - "integrity": "sha512-gklfI/n+9rTh8nYaSJXlCo3nOKqMNkxuGpTn/Qm0gstL3ywTr9/WRKznE+oy6fvfolH6dF+QM4nCo8yPLdvGJg==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-minify-gradients": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-6.0.3.tgz", - "integrity": "sha512-4KXAHrYlzF0Rr7uc4VrfwDJ2ajrtNEpNEuLxFgwkhFZ56/7gaE4Nr49nLsQDZyUe+ds+kEhf+YAUolJiYXF8+Q==", - "license": "MIT", - "dependencies": { - "colord": "^2.9.3", - "cssnano-utils": "^4.0.2", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-minify-params": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-6.1.0.tgz", - "integrity": "sha512-bmSKnDtyyE8ujHQK0RQJDIKhQ20Jq1LYiez54WiaOoBtcSuflfK3Nm596LvbtlFcpipMjgClQGyGr7GAs+H1uA==", - "license": "MIT", - "dependencies": { - "browserslist": "^4.23.0", - "cssnano-utils": "^4.0.2", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-minify-selectors": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-6.0.4.tgz", - "integrity": "sha512-L8dZSwNLgK7pjTto9PzWRoMbnLq5vsZSTu8+j1P/2GB8qdtGQfn+K1uSvFgYvgh83cbyxT5m43ZZhUMTJDSClQ==", - "license": "MIT", - "dependencies": { - "postcss-selector-parser": "^6.0.16" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-modules-extract-imports": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", - "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", - "license": "ISC", - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-local-by-default": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz", - "integrity": "sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==", - "license": "MIT", - "dependencies": { - "icss-utils": "^5.0.0", - "postcss-selector-parser": "^7.0.0", - "postcss-value-parser": "^4.1.0" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-local-by-default/node_modules/postcss-selector-parser": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", - "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-modules-scope": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz", - "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==", - "license": "ISC", - "dependencies": { - "postcss-selector-parser": "^7.0.0" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-scope/node_modules/postcss-selector-parser": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", - "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-modules-values": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", - "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", - "license": "ISC", - "dependencies": { - "icss-utils": "^5.0.0" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-nesting": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-13.0.2.tgz", - "integrity": "sha512-1YCI290TX+VP0U/K/aFxzHzQWHWURL+CtHMSbex1lCdpXD1SoR2sYuxDu5aNI9lPoXpKTCggFZiDJbwylU0LEQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/selector-resolve-nested": "^3.1.0", - "@csstools/selector-specificity": "^5.0.0", - "postcss-selector-parser": "^7.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-nesting/node_modules/@csstools/selector-resolve-nested": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@csstools/selector-resolve-nested/-/selector-resolve-nested-3.1.0.tgz", - "integrity": "sha512-mf1LEW0tJLKfWyvn5KdDrhpxHyuxpbNwTIwOYLIvsTffeyOf85j5oIzfG0yosxDgx/sswlqBnESYUcQH0vgZ0g==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss-selector-parser": "^7.0.0" - } - }, - "node_modules/postcss-nesting/node_modules/@csstools/selector-specificity": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", - "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss-selector-parser": "^7.0.0" - } - }, - "node_modules/postcss-nesting/node_modules/postcss-selector-parser": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", - "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-normalize-charset": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-6.0.2.tgz", - "integrity": "sha512-a8N9czmdnrjPHa3DeFlwqst5eaL5W8jYu3EBbTTkI5FHkfMhFZh1EGbku6jhHhIzTA6tquI2P42NtZ59M/H/kQ==", - "license": "MIT", - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-display-values": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-6.0.2.tgz", - "integrity": "sha512-8H04Mxsb82ON/aAkPeq8kcBbAtI5Q2a64X/mnRRfPXBq7XeogoQvReqxEfc0B4WPq1KimjezNC8flUtC3Qz6jg==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-positions": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-6.0.2.tgz", - "integrity": "sha512-/JFzI441OAB9O7VnLA+RtSNZvQ0NCFZDOtp6QPFo1iIyawyXg0YI3CYM9HBy1WvwCRHnPep/BvI1+dGPKoXx/Q==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-repeat-style": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-6.0.2.tgz", - "integrity": "sha512-YdCgsfHkJ2jEXwR4RR3Tm/iOxSfdRt7jplS6XRh9Js9PyCR/aka/FCb6TuHT2U8gQubbm/mPmF6L7FY9d79VwQ==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-string": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-6.0.2.tgz", - "integrity": "sha512-vQZIivlxlfqqMp4L9PZsFE4YUkWniziKjQWUtsxUiVsSSPelQydwS8Wwcuw0+83ZjPWNTl02oxlIvXsmmG+CiQ==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-timing-functions": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-6.0.2.tgz", - "integrity": "sha512-a+YrtMox4TBtId/AEwbA03VcJgtyW4dGBizPl7e88cTFULYsprgHWTbfyjSLyHeBcK/Q9JhXkt2ZXiwaVHoMzA==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-unicode": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-6.1.0.tgz", - "integrity": "sha512-QVC5TQHsVj33otj8/JD869Ndr5Xcc/+fwRh4HAsFsAeygQQXm+0PySrKbr/8tkDKzW+EVT3QkqZMfFrGiossDg==", - "license": "MIT", - "dependencies": { - "browserslist": "^4.23.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-url": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-6.0.2.tgz", - "integrity": "sha512-kVNcWhCeKAzZ8B4pv/DnrU1wNh458zBNp8dh4y5hhxih5RZQ12QWMuQrDgPRw3LRl8mN9vOVfHl7uhvHYMoXsQ==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-normalize-whitespace": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-6.0.2.tgz", - "integrity": "sha512-sXZ2Nj1icbJOKmdjXVT9pnyHQKiSAyuNQHSgRCUgThn2388Y9cGVDR+E9J9iAYbSbLHI+UUwLVl1Wzco/zgv0Q==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-opacity-percentage": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-opacity-percentage/-/postcss-opacity-percentage-3.0.0.tgz", - "integrity": "sha512-K6HGVzyxUxd/VgZdX04DCtdwWJ4NGLG212US4/LA1TLAbHgmAsTWVR86o+gGIbFtnTkfOpb9sCRBx8K7HO66qQ==", - "funding": [ - { - "type": "kofi", - "url": "https://ko-fi.com/mrcgrtz" - }, - { - "type": "liberapay", - "url": "https://liberapay.com/mrcgrtz" - } - ], - "license": "MIT", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-ordered-values": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-6.0.2.tgz", - "integrity": "sha512-VRZSOB+JU32RsEAQrO94QPkClGPKJEL/Z9PCBImXMhIeK5KAYo6slP/hBYlLgrCjFxyqvn5VC81tycFEDBLG1Q==", - "license": "MIT", - "dependencies": { - "cssnano-utils": "^4.0.2", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-overflow-shorthand": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-6.0.0.tgz", - "integrity": "sha512-BdDl/AbVkDjoTofzDQnwDdm/Ym6oS9KgmO7Gr+LHYjNWJ6ExORe4+3pcLQsLA9gIROMkiGVjjwZNoL/mpXHd5Q==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-page-break": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-3.0.4.tgz", - "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==", - "license": "MIT", - "peerDependencies": { - "postcss": "^8" - } - }, - "node_modules/postcss-place": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-10.0.0.tgz", - "integrity": "sha512-5EBrMzat2pPAxQNWYavwAfoKfYcTADJ8AXGVPcUZ2UkNloUTWzJQExgrzrDkh3EKzmAx1evfTAzF9I8NGcc+qw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-preset-env": { - "version": "10.2.3", - "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-10.2.3.tgz", - "integrity": "sha512-zlQN1yYmA7lFeM1wzQI14z97mKoM8qGng+198w1+h6sCud/XxOjcKtApY9jWr7pXNS3yHDEafPlClSsWnkY8ow==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "@csstools/postcss-cascade-layers": "^5.0.1", - "@csstools/postcss-color-function": "^4.0.10", - "@csstools/postcss-color-mix-function": "^3.0.10", - "@csstools/postcss-color-mix-variadic-function-arguments": "^1.0.0", - "@csstools/postcss-content-alt-text": "^2.0.6", - "@csstools/postcss-exponential-functions": "^2.0.9", - "@csstools/postcss-font-format-keywords": "^4.0.0", - "@csstools/postcss-gamut-mapping": "^2.0.10", - "@csstools/postcss-gradients-interpolation-method": "^5.0.10", - "@csstools/postcss-hwb-function": "^4.0.10", - "@csstools/postcss-ic-unit": "^4.0.2", - "@csstools/postcss-initial": "^2.0.1", - "@csstools/postcss-is-pseudo-class": "^5.0.3", - "@csstools/postcss-light-dark-function": "^2.0.9", - "@csstools/postcss-logical-float-and-clear": "^3.0.0", - "@csstools/postcss-logical-overflow": "^2.0.0", - "@csstools/postcss-logical-overscroll-behavior": "^2.0.0", - "@csstools/postcss-logical-resize": "^3.0.0", - "@csstools/postcss-logical-viewport-units": "^3.0.4", - "@csstools/postcss-media-minmax": "^2.0.9", - "@csstools/postcss-media-queries-aspect-ratio-number-values": "^3.0.5", - "@csstools/postcss-nested-calc": "^4.0.0", - "@csstools/postcss-normalize-display-values": "^4.0.0", - "@csstools/postcss-oklab-function": "^4.0.10", - "@csstools/postcss-progressive-custom-properties": "^4.1.0", - "@csstools/postcss-random-function": "^2.0.1", - "@csstools/postcss-relative-color-syntax": "^3.0.10", - "@csstools/postcss-scope-pseudo-class": "^4.0.1", - "@csstools/postcss-sign-functions": "^1.1.4", - "@csstools/postcss-stepped-value-functions": "^4.0.9", - "@csstools/postcss-text-decoration-shorthand": "^4.0.2", - "@csstools/postcss-trigonometric-functions": "^4.0.9", - "@csstools/postcss-unset-value": "^4.0.0", - "autoprefixer": "^10.4.21", - "browserslist": "^4.25.0", - "css-blank-pseudo": "^7.0.1", - "css-has-pseudo": "^7.0.2", - "css-prefers-color-scheme": "^10.0.0", - "cssdb": "^8.3.0", - "postcss-attribute-case-insensitive": "^7.0.1", - "postcss-clamp": "^4.1.0", - "postcss-color-functional-notation": "^7.0.10", - "postcss-color-hex-alpha": "^10.0.0", - "postcss-color-rebeccapurple": "^10.0.0", - "postcss-custom-media": "^11.0.6", - "postcss-custom-properties": "^14.0.6", - "postcss-custom-selectors": "^8.0.5", - "postcss-dir-pseudo-class": "^9.0.1", - "postcss-double-position-gradients": "^6.0.2", - "postcss-focus-visible": "^10.0.1", - "postcss-focus-within": "^9.0.1", - "postcss-font-variant": "^5.0.0", - "postcss-gap-properties": "^6.0.0", - "postcss-image-set-function": "^7.0.0", - "postcss-lab-function": "^7.0.10", - "postcss-logical": "^8.1.0", - "postcss-nesting": "^13.0.2", - "postcss-opacity-percentage": "^3.0.0", - "postcss-overflow-shorthand": "^6.0.0", - "postcss-page-break": "^3.0.4", - "postcss-place": "^10.0.0", - "postcss-pseudo-class-any-link": "^10.0.1", - "postcss-replace-overflow-wrap": "^4.0.0", - "postcss-selector-not": "^8.0.1" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-pseudo-class-any-link": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-10.0.1.tgz", - "integrity": "sha512-3el9rXlBOqTFaMFkWDOkHUTQekFIYnaQY55Rsp8As8QQkpiSgIYEcF/6Ond93oHiDsGb4kad8zjt+NPlOC1H0Q==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "dependencies": { - "postcss-selector-parser": "^7.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-pseudo-class-any-link/node_modules/postcss-selector-parser": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", - "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-reduce-idents": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-6.0.3.tgz", - "integrity": "sha512-G3yCqZDpsNPoQgbDUy3T0E6hqOQ5xigUtBQyrmq3tn2GxlyiL0yyl7H+T8ulQR6kOcHJ9t7/9H4/R2tv8tJbMA==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-reduce-initial": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-6.1.0.tgz", - "integrity": "sha512-RarLgBK/CrL1qZags04oKbVbrrVK2wcxhvta3GCxrZO4zveibqbRPmm2VI8sSgCXwoUHEliRSbOfpR0b/VIoiw==", - "license": "MIT", - "dependencies": { - "browserslist": "^4.23.0", - "caniuse-api": "^3.0.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-reduce-transforms": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-6.0.2.tgz", - "integrity": "sha512-sB+Ya++3Xj1WaT9+5LOOdirAxP7dJZms3GRcYheSPi1PiTMigsxHAdkrbItHxwYHr4kt1zL7mmcHstgMYT+aiA==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-replace-overflow-wrap": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz", - "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==", - "license": "MIT", - "peerDependencies": { - "postcss": "^8.0.3" - } - }, - "node_modules/postcss-selector-not": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-8.0.1.tgz", - "integrity": "sha512-kmVy/5PYVb2UOhy0+LqUYAhKj7DUGDpSWa5LZqlkWJaaAV+dxxsOG3+St0yNLu6vsKD7Dmqx+nWQt0iil89+WA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "dependencies": { - "postcss-selector-parser": "^7.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-selector-not/node_modules/postcss-selector-parser": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", - "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-selector-parser": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", - "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-sort-media-queries": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/postcss-sort-media-queries/-/postcss-sort-media-queries-5.2.0.tgz", - "integrity": "sha512-AZ5fDMLD8SldlAYlvi8NIqo0+Z8xnXU2ia0jxmuhxAU+Lqt9K+AlmLNJ/zWEnE9x+Zx3qL3+1K20ATgNOr3fAA==", - "license": "MIT", - "dependencies": { - "sort-css-media-queries": "2.2.0" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "postcss": "^8.4.23" - } - }, - "node_modules/postcss-svgo": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-6.0.3.tgz", - "integrity": "sha512-dlrahRmxP22bX6iKEjOM+c8/1p+81asjKT+V5lrgOH944ryx/OHpclnIbGsKVd3uWOXFLYJwCVf0eEkJGvO96g==", - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.2.0", - "svgo": "^3.2.0" - }, - "engines": { - "node": "^14 || ^16 || >= 18" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-unique-selectors": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-6.0.4.tgz", - "integrity": "sha512-K38OCaIrO8+PzpArzkLKB42dSARtC2tmG6PvD4b1o1Q2E9Os8jzfWFfSy/rixsHwohtsDdFtAWGjFVFUdwYaMg==", - "license": "MIT", - "dependencies": { - "postcss-selector-parser": "^6.0.16" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "license": "MIT" - }, - "node_modules/postcss-zindex": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-6.0.2.tgz", - "integrity": "sha512-5BxW9l1evPB/4ZIc+2GobEBoKC+h8gPGCMi+jxsYvd2x0mjq7wazk6DrP71pStqxE9Foxh5TVnonbWpFZzXaYg==", - "license": "MIT", - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/pretty-error": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", - "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", - "license": "MIT", - "dependencies": { - "lodash": "^4.17.20", - "renderkid": "^3.0.0" - } - }, - "node_modules/pretty-time": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pretty-time/-/pretty-time-1.1.0.tgz", - "integrity": "sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/prism-react-renderer": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-2.4.1.tgz", - "integrity": "sha512-ey8Ls/+Di31eqzUxC46h8MksNuGx/n0AAC8uKpwFau4RPDYLuE3EXTp8N8G2vX2N7UC/+IXeNUnlWBGGcAG+Ig==", - "license": "MIT", - "dependencies": { - "@types/prismjs": "^1.26.0", - "clsx": "^2.0.0" - }, - "peerDependencies": { - "react": ">=16.0.0" - } - }, - "node_modules/prismjs": { - "version": "1.30.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz", - "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "license": "MIT" - }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "license": "MIT", - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/prop-types": { - "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" - } - }, - "node_modules/property-information": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", - "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/proto-list": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", - "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", - "license": "ISC" - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "license": "MIT", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/proxy-addr/node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/pupa": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pupa/-/pupa-3.1.0.tgz", - "integrity": "sha512-FLpr4flz5xZTSJxSeaheeMKN/EDzMdK7b8PTOC6a5PYFKTucWbdqjgqaEyH0shFiSJrVB1+Qqi4Tk19ccU6Aug==", - "license": "MIT", - "dependencies": { - "escape-goat": "^4.0.0" - }, - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/qs": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.0.6" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "license": "MIT", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/range-parser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", - "integrity": "sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/raw-body/node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/rc/node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "license": "ISC" - }, - "node_modules/rc/node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", - "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-dom": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", - "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.2" - }, - "peerDependencies": { - "react": "^18.3.1" - } - }, - "node_modules/react-fast-compare": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", - "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==", - "license": "MIT" - }, - "node_modules/react-helmet-async": { - "name": "@slorber/react-helmet-async", - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@slorber/react-helmet-async/-/react-helmet-async-1.3.0.tgz", - "integrity": "sha512-e9/OK8VhwUSc67diWI8Rb3I0YgI9/SBQtnhe9aEuK6MhZm7ntZZimXgwXnd8W96YTmSOb9M4d8LwhRZyhWr/1A==", - "license": "Apache-2.0", - "dependencies": { - "@babel/runtime": "^7.12.5", - "invariant": "^2.2.4", - "prop-types": "^15.7.2", - "react-fast-compare": "^3.2.0", - "shallowequal": "^1.1.0" - }, - "peerDependencies": { - "react": "^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "react-dom": "^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" - } - }, - "node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "license": "MIT" - }, - "node_modules/react-json-view-lite": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/react-json-view-lite/-/react-json-view-lite-2.4.1.tgz", - "integrity": "sha512-fwFYknRIBxjbFm0kBDrzgBy1xa5tDg2LyXXBepC5f1b+MY3BUClMCsvanMPn089JbV1Eg3nZcrp0VCuH43aXnA==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "react": "^18.0.0 || ^19.0.0" - } - }, - "node_modules/react-loadable": { - "name": "@docusaurus/react-loadable", - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-6.0.0.tgz", - "integrity": "sha512-YMMxTUQV/QFSnbgrP3tjDzLHRg7vsbMn8e9HAa8o/1iXoiomo48b7sk/kkmWEuWNDPJVlKSJRB6Y2fHqdJk+SQ==", - "license": "MIT", - "dependencies": { - "@types/react": "*" - }, - "peerDependencies": { - "react": "*" - } - }, - "node_modules/react-loadable-ssr-addon-v5-slorber": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/react-loadable-ssr-addon-v5-slorber/-/react-loadable-ssr-addon-v5-slorber-1.0.1.tgz", - "integrity": "sha512-lq3Lyw1lGku8zUEJPDxsNm1AfYHBrO9Y1+olAYwpUJ2IGFBskM0DMKok97A6LWUpHm+o7IvQBOWu9MLenp9Z+A==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.10.3" - }, - "engines": { - "node": ">=10.13.0" - }, - "peerDependencies": { - "react-loadable": "*", - "webpack": ">=4.41.1 || 5.x" - } - }, - "node_modules/react-router": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz", - "integrity": "sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.12.13", - "history": "^4.9.0", - "hoist-non-react-statics": "^3.1.0", - "loose-envify": "^1.3.1", - "path-to-regexp": "^1.7.0", - "prop-types": "^15.6.2", - "react-is": "^16.6.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0" - }, - "peerDependencies": { - "react": ">=15" - } - }, - "node_modules/react-router-config": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/react-router-config/-/react-router-config-5.1.1.tgz", - "integrity": "sha512-DuanZjaD8mQp1ppHjgnnUnyOlqYXZVjnov/JzFhjLEwd3Z4dYjMSnqrEzzGThH47vpCOqPPwJM2FtthLeJ8Pbg==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.1.2" - }, - "peerDependencies": { - "react": ">=15", - "react-router": ">=5" - } - }, - "node_modules/react-router-dom": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.4.tgz", - "integrity": "sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.12.13", - "history": "^4.9.0", - "loose-envify": "^1.3.1", - "prop-types": "^15.6.2", - "react-router": "5.3.4", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0" - }, - "peerDependencies": { - "react": ">=15" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/recma-build-jsx": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/recma-build-jsx/-/recma-build-jsx-1.0.0.tgz", - "integrity": "sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "estree-util-build-jsx": "^3.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/recma-jsx": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/recma-jsx/-/recma-jsx-1.0.0.tgz", - "integrity": "sha512-5vwkv65qWwYxg+Atz95acp8DMu1JDSqdGkA2Of1j6rCreyFUE/gp15fC8MnGEuG1W68UKjM6x6+YTWIh7hZM/Q==", - "license": "MIT", - "dependencies": { - "acorn-jsx": "^5.0.0", - "estree-util-to-js": "^2.0.0", - "recma-parse": "^1.0.0", - "recma-stringify": "^1.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/recma-parse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/recma-parse/-/recma-parse-1.0.0.tgz", - "integrity": "sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "esast-util-from-js": "^2.0.0", - "unified": "^11.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/recma-stringify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/recma-stringify/-/recma-stringify-1.0.0.tgz", - "integrity": "sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "estree-util-to-js": "^2.0.0", - "unified": "^11.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "license": "MIT" - }, - "node_modules/regenerate-unicode-properties": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz", - "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==", - "license": "MIT", - "dependencies": { - "regenerate": "^1.4.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regexpu-core": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz", - "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==", - "license": "MIT", - "dependencies": { - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.2.0", - "regjsgen": "^0.8.0", - "regjsparser": "^0.12.0", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/registry-auth-token": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.1.0.tgz", - "integrity": "sha512-GdekYuwLXLxMuFTwAPg5UKGLW/UXzQrZvH/Zj791BQif5T05T0RsaLfHc9q3ZOKi7n+BoprPD9mJ0O0k4xzUlw==", - "license": "MIT", - "dependencies": { - "@pnpm/npm-conf": "^2.1.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/registry-url": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-6.0.1.tgz", - "integrity": "sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==", - "license": "MIT", - "dependencies": { - "rc": "1.2.8" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/regjsgen": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", - "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", - "license": "MIT" - }, - "node_modules/regjsparser": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz", - "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==", - "license": "BSD-2-Clause", - "dependencies": { - "jsesc": "~3.0.2" - }, - "bin": { - "regjsparser": "bin/parser" - } - }, - "node_modules/regjsparser/node_modules/jsesc": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", - "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/rehype-raw": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", - "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "hast-util-raw": "^9.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-recma": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/rehype-recma/-/rehype-recma-1.0.0.tgz", - "integrity": "sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "@types/hast": "^3.0.0", - "hast-util-to-estree": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/relateurl": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/remark-directive": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-directive/-/remark-directive-3.0.1.tgz", - "integrity": "sha512-gwglrEQEZcZYgVyG1tQuA+h58EZfq5CSULw7J90AFuCTyib1thgHPoqQ+h9iFvU6R+vnZ5oNFQR5QKgGpk741A==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-directive": "^3.0.0", - "micromark-extension-directive": "^3.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-emoji": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-emoji/-/remark-emoji-4.0.1.tgz", - "integrity": "sha512-fHdvsTR1dHkWKev9eNyhTo4EFwbUvJ8ka9SgeWkMPYFX4WoI7ViVBms3PjlQYgw5TLvNQso3GUB/b/8t3yo+dg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.2", - "emoticon": "^4.0.1", - "mdast-util-find-and-replace": "^3.0.1", - "node-emoji": "^2.1.0", - "unified": "^11.0.4" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "node_modules/remark-frontmatter": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-5.0.0.tgz", - "integrity": "sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-frontmatter": "^2.0.0", - "micromark-extension-frontmatter": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-gfm": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", - "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-gfm": "^3.0.0", - "micromark-extension-gfm": "^3.0.0", - "remark-parse": "^11.0.0", - "remark-stringify": "^11.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-mdx": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.1.0.tgz", - "integrity": "sha512-Ngl/H3YXyBV9RcRNdlYsZujAmhsxwzxpDzpDEhFBVAGthS4GDgnctpDjgFl/ULx5UEDzqtW1cyBSNKqYYrqLBA==", - "license": "MIT", - "dependencies": { - "mdast-util-mdx": "^3.0.0", - "micromark-extension-mdxjs": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-parse": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", - "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-from-markdown": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-rehype": { - "version": "11.1.2", - "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz", - "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "mdast-util-to-hast": "^13.0.0", - "unified": "^11.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-stringify": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", - "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-to-markdown": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/renderkid": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", - "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", - "license": "MIT", - "dependencies": { - "css-select": "^4.1.3", - "dom-converter": "^0.2.0", - "htmlparser2": "^6.1.0", - "lodash": "^4.17.21", - "strip-ansi": "^6.0.1" - } - }, - "node_modules/renderkid/node_modules/css-select": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", - "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/renderkid/node_modules/dom-serializer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", - "license": "MIT", - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/renderkid/node_modules/domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", - "license": "BSD-2-Clause", - "dependencies": { - "domelementtype": "^2.2.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/renderkid/node_modules/domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "license": "BSD-2-Clause", - "dependencies": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/renderkid/node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "license": "BSD-2-Clause", - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/renderkid/node_modules/htmlparser2": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", - "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "MIT", - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.0.0", - "domutils": "^2.5.2", - "entities": "^2.0.0" - } - }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", - "license": "MIT", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-like": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz", - "integrity": "sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==", - "engines": { - "node": "*" - } - }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "license": "MIT" - }, - "node_modules/resolve": { - "version": "1.22.10", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", - "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", - "license": "MIT", - "dependencies": { - "is-core-module": "^2.16.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-alpn": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", - "license": "MIT" - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/resolve-pathname": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", - "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==", - "license": "MIT" - }, - "node_modules/responselike": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", - "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", - "license": "MIT", - "dependencies": { - "lowercase-keys": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/retry": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/reusify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rtlcss": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-4.3.0.tgz", - "integrity": "sha512-FI+pHEn7Wc4NqKXMXFM+VAYKEj/mRIcW4h24YVwVtyjI+EqGrLc2Hx/Ny0lrZ21cBWU2goLy36eqMcNj3AQJig==", - "license": "MIT", - "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0", - "postcss": "^8.4.21", - "strip-json-comments": "^3.1.1" - }, - "bin": { - "rtlcss": "bin/rtlcss.js" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "license": "MIT" - }, - "node_modules/sax": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", - "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", - "license": "ISC" - }, - "node_modules/scheduler": { - "version": "0.23.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", - "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.1.0" - } - }, - "node_modules/schema-dts": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/schema-dts/-/schema-dts-1.1.5.tgz", - "integrity": "sha512-RJr9EaCmsLzBX2NDiO5Z3ux2BVosNZN5jo0gWgsyKvxKIUL5R3swNvoorulAeL9kLB0iTSX7V6aokhla2m7xbg==", - "license": "Apache-2.0" - }, - "node_modules/schema-utils": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz", - "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==", - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/search-insights": { - "version": "2.17.3", - "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.17.3.tgz", - "integrity": "sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ==", - "license": "MIT", - "peer": true - }, - "node_modules/section-matter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", - "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", - "license": "MIT", - "dependencies": { - "extend-shallow": "^2.0.1", - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/select-hose": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", - "license": "MIT" - }, - "node_modules/selfsigned": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", - "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", - "license": "MIT", - "dependencies": { - "@types/node-forge": "^1.3.0", - "node-forge": "^1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-4.0.0.tgz", - "integrity": "sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==", - "license": "MIT", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/send": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", - "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", - "license": "MIT", - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/send/node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/send/node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", - "license": "BSD-3-Clause", - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/serve-handler": { - "version": "6.1.6", - "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.6.tgz", - "integrity": "sha512-x5RL9Y2p5+Sh3D38Fh9i/iQ5ZK+e4xuXRd/pGbM4D13tgo/MGwbttUk8emytcr1YYzBYs+apnUngBDFYfpjPuQ==", - "license": "MIT", - "dependencies": { - "bytes": "3.0.0", - "content-disposition": "0.5.2", - "mime-types": "2.1.18", - "minimatch": "3.1.2", - "path-is-inside": "1.0.2", - "path-to-regexp": "3.3.0", - "range-parser": "1.2.0" - } - }, - "node_modules/serve-handler/node_modules/path-to-regexp": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.3.0.tgz", - "integrity": "sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==", - "license": "MIT" - }, - "node_modules/serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", - "license": "MIT", - "dependencies": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/serve-index/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/serve-index/node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-index/node_modules/http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", - "license": "MIT", - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-index/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", - "license": "ISC" - }, - "node_modules/serve-index/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/serve-index/node_modules/setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "license": "ISC" - }, - "node_modules/serve-index/node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-static": { - "version": "1.16.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", - "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", - "license": "MIT", - "dependencies": { - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.19.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "license": "MIT", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "license": "ISC" - }, - "node_modules/shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "license": "MIT", - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shallowequal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", - "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==", - "license": "MIT" - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/shell-quote": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", - "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", - "side-channel-map": "^1.0.1", - "side-channel-weakmap": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-weakmap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3", - "side-channel-map": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "license": "ISC" - }, - "node_modules/sirv": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", - "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", - "license": "MIT", - "dependencies": { - "@polka/url": "^1.0.0-next.24", - "mrmime": "^2.0.0", - "totalist": "^3.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "license": "MIT" - }, - "node_modules/sitemap": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-7.1.2.tgz", - "integrity": "sha512-ARCqzHJ0p4gWt+j7NlU5eDlIO9+Rkr/JhPFZKKQ1l5GCus7rJH4UdrlVAh0xC/gDS/Qir2UMxqYNHtsKr2rpCw==", - "license": "MIT", - "dependencies": { - "@types/node": "^17.0.5", - "@types/sax": "^1.2.1", - "arg": "^5.0.0", - "sax": "^1.2.4" - }, - "bin": { - "sitemap": "dist/cli.js" - }, - "engines": { - "node": ">=12.0.0", - "npm": ">=5.6.0" - } - }, - "node_modules/sitemap/node_modules/@types/node": { - "version": "17.0.45", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", - "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==", - "license": "MIT" - }, - "node_modules/skin-tone": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz", - "integrity": "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==", - "license": "MIT", - "dependencies": { - "unicode-emoji-modifier-base": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/snake-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", - "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", - "license": "MIT", - "dependencies": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/sockjs": { - "version": "0.3.24", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", - "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", - "license": "MIT", - "dependencies": { - "faye-websocket": "^0.11.3", - "uuid": "^8.3.2", - "websocket-driver": "^0.7.4" - } - }, - "node_modules/sort-css-media-queries": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/sort-css-media-queries/-/sort-css-media-queries-2.2.0.tgz", - "integrity": "sha512-0xtkGhWCC9MGt/EzgnvbbbKhqWjl1+/rncmhTh5qCpbYguXh6S/qwePfv/JQ8jePXXmqingylxoC49pCkSPIbA==", - "license": "MIT", - "engines": { - "node": ">= 6.3.0" - } - }, - "node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "license": "BSD-3-Clause", - "engines": { - "node": ">= 8" - } - }, - "node_modules/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==", - "license": "BSD-3-Clause", - "engines": { - "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==", - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-support/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==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.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==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/spdy": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", - "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", - "license": "MIT", - "dependencies": { - "debug": "^4.1.0", - "handle-thing": "^2.0.0", - "http-deceiver": "^1.2.7", - "select-hose": "^2.0.0", - "spdy-transport": "^3.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/spdy-transport": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", - "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", - "license": "MIT", - "dependencies": { - "debug": "^4.1.0", - "detect-node": "^2.0.4", - "hpack.js": "^2.1.6", - "obuf": "^1.1.2", - "readable-stream": "^3.0.6", - "wbuf": "^1.7.3" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "license": "BSD-3-Clause" - }, - "node_modules/srcset": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/srcset/-/srcset-4.0.0.tgz", - "integrity": "sha512-wvLeHgcVHKO8Sc/H/5lkGreJQVeYMm9rlmt8PuR1xE31rIuXhuzznUUqAt8MqLhB3MqJdFzlNAfpcWnxiFUcPw==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/std-env": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.9.0.tgz", - "integrity": "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==", - "license": "MIT" - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/string-width/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/string-width/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/stringify-entities": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", - "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", - "license": "MIT", - "dependencies": { - "character-entities-html4": "^2.0.0", - "character-entities-legacy": "^3.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/stringify-object": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", - "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", - "license": "BSD-2-Clause", - "dependencies": { - "get-own-enumerable-property-symbols": "^3.0.0", - "is-obj": "^1.0.1", - "is-regexp": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", - "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/style-to-js": { - "version": "1.1.17", - "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.17.tgz", - "integrity": "sha512-xQcBGDxJb6jjFCTzvQtfiPn6YvvP2O8U1MDIPNfJQlWMYfktPy+iGsHE7cssjs7y84d9fQaK4UF3RIJaAHSoYA==", - "license": "MIT", - "dependencies": { - "style-to-object": "1.0.9" - } - }, - "node_modules/style-to-object": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.9.tgz", - "integrity": "sha512-G4qppLgKu/k6FwRpHiGiKPaPTFcG3g4wNVX/Qsfu+RqQM30E7Tyu/TEgxcL9PNLF5pdRLwQdE3YKKf+KF2Dzlw==", - "license": "MIT", - "dependencies": { - "inline-style-parser": "0.2.4" - } - }, - "node_modules/stylehacks": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-6.1.1.tgz", - "integrity": "sha512-gSTTEQ670cJNoaeIp9KX6lZmm8LJ3jPB5yJmX8Zq/wQxOsAFXV3qjWzHas3YYk1qesuVIyYWWUpZ0vSE/dTSGg==", - "license": "MIT", - "dependencies": { - "browserslist": "^4.23.0", - "postcss-selector-parser": "^6.0.16" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/svg-parser": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", - "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==", - "license": "MIT" - }, - "node_modules/svgo": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.2.tgz", - "integrity": "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==", - "license": "MIT", - "dependencies": { - "@trysound/sax": "0.2.0", - "commander": "^7.2.0", - "css-select": "^5.1.0", - "css-tree": "^2.3.1", - "css-what": "^6.1.0", - "csso": "^5.0.5", - "picocolors": "^1.0.0" - }, - "bin": { - "svgo": "bin/svgo" - }, - "engines": { - "node": ">=14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/svgo" - } - }, - "node_modules/svgo/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "license": "MIT", - "engines": { - "node": ">= 10" - } - }, - "node_modules/tapable": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz", - "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/terser": { - "version": "5.43.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.43.1.tgz", - "integrity": "sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==", - "license": "BSD-2-Clause", - "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.14.0", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/terser-webpack-plugin": { - "version": "5.3.14", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz", - "integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==", - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.25", - "jest-worker": "^27.4.5", - "schema-utils": "^4.3.0", - "serialize-javascript": "^6.0.2", - "terser": "^5.31.1" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "uglify-js": { - "optional": true - } - } - }, - "node_modules/terser-webpack-plugin/node_modules/jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/terser-webpack-plugin/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "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==", - "license": "MIT" - }, - "node_modules/thunky": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", - "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", - "license": "MIT" - }, - "node_modules/tiny-invariant": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", - "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", - "license": "MIT" - }, - "node_modules/tiny-warning": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", - "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==", - "license": "MIT" - }, - "node_modules/tinypool": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", - "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", - "license": "MIT", - "engines": { - "node": "^18.0.0 || >=20.0.0" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "license": "MIT", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/totalist": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", - "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/trim-lines": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", - "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/trough": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", - "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD" - }, - "node_modules/type-fest": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "license": "MIT", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/type-is/node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/type-is/node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "license": "MIT", - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/typescript": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", - "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", - "devOptional": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/undici-types": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz", - "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==", - "license": "MIT" - }, - "node_modules/unicode-canonical-property-names-ecmascript": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", - "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-emoji-modifier-base": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz", - "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", - "license": "MIT", - "dependencies": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz", - "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-property-aliases-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", - "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/unified": { - "version": "11.0.5", - "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", - "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "bail": "^2.0.0", - "devlop": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^4.0.0", - "trough": "^2.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unique-string": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", - "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==", - "license": "MIT", - "dependencies": { - "crypto-random-string": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/unist-util-is": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-position": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", - "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-position-from-estree": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz", - "integrity": "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit": { - "version": "5.0.0", - "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==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit-parents": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", - "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "license": "MIT", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", - "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "escalade": "^3.2.0", - "picocolors": "^1.1.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/update-notifier": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-6.0.2.tgz", - "integrity": "sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og==", - "license": "BSD-2-Clause", - "dependencies": { - "boxen": "^7.0.0", - "chalk": "^5.0.1", - "configstore": "^6.0.0", - "has-yarn": "^3.0.0", - "import-lazy": "^4.0.0", - "is-ci": "^3.0.1", - "is-installed-globally": "^0.4.0", - "is-npm": "^6.0.0", - "is-yarn-global": "^0.4.0", - "latest-version": "^7.0.0", - "pupa": "^3.1.0", - "semver": "^7.3.7", - "semver-diff": "^4.0.0", - "xdg-basedir": "^5.1.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/yeoman/update-notifier?sponsor=1" - } - }, - "node_modules/update-notifier/node_modules/boxen": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.1.1.tgz", - "integrity": "sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==", - "license": "MIT", - "dependencies": { - "ansi-align": "^3.0.1", - "camelcase": "^7.0.1", - "chalk": "^5.2.0", - "cli-boxes": "^3.0.0", - "string-width": "^5.1.2", - "type-fest": "^2.13.0", - "widest-line": "^4.0.1", - "wrap-ansi": "^8.1.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/update-notifier/node_modules/camelcase": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", - "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==", - "license": "MIT", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/update-notifier/node_modules/chalk": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", - "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/url-loader": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz", - "integrity": "sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==", - "license": "MIT", - "dependencies": { - "loader-utils": "^2.0.0", - "mime-types": "^2.1.27", - "schema-utils": "^3.0.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "file-loader": "*", - "webpack": "^4.0.0 || ^5.0.0" - }, - "peerDependenciesMeta": { - "file-loader": { - "optional": true - } - } - }, - "node_modules/url-loader/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/url-loader/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "license": "MIT", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/url-loader/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "license": "MIT" - }, - "node_modules/url-loader/node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/url-loader/node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/url-loader/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "license": "MIT" - }, - "node_modules/utila": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==", - "license": "MIT" - }, - "node_modules/utility-types": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.11.0.tgz", - "integrity": "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==", - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "license": "MIT", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/value-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", - "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==", - "license": "MIT" - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/vfile": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", - "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile-location": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.3.tgz", - "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile-message": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", - "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/watchpack": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz", - "integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==", - "license": "MIT", - "dependencies": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/wbuf": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", - "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", - "license": "MIT", - "dependencies": { - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/web-namespaces": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", - "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/webpack": { - "version": "5.99.9", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.99.9.tgz", - "integrity": "sha512-brOPwM3JnmOa+7kd3NsmOUOwbDAj8FT9xDsG3IW0MgbN9yZV7Oi/s/+MNQ/EcSMqw7qfoRyXPoeEWT8zLVdVGg==", - "license": "MIT", - "dependencies": { - "@types/eslint-scope": "^3.7.7", - "@types/estree": "^1.0.6", - "@types/json-schema": "^7.0.15", - "@webassemblyjs/ast": "^1.14.1", - "@webassemblyjs/wasm-edit": "^1.14.1", - "@webassemblyjs/wasm-parser": "^1.14.1", - "acorn": "^8.14.0", - "browserslist": "^4.24.0", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.1", - "es-module-lexer": "^1.2.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.11", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^4.3.2", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.11", - "watchpack": "^2.4.1", - "webpack-sources": "^3.2.3" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-bundle-analyzer": { - "version": "4.10.2", - "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.2.tgz", - "integrity": "sha512-vJptkMm9pk5si4Bv922ZbKLV8UTT4zib4FPgXMhgzUny0bfDDkLXAVQs3ly3fS4/TN9ROFtb0NFrm04UXFE/Vw==", - "license": "MIT", - "dependencies": { - "@discoveryjs/json-ext": "0.5.7", - "acorn": "^8.0.4", - "acorn-walk": "^8.0.0", - "commander": "^7.2.0", - "debounce": "^1.2.1", - "escape-string-regexp": "^4.0.0", - "gzip-size": "^6.0.0", - "html-escaper": "^2.0.2", - "opener": "^1.5.2", - "picocolors": "^1.0.0", - "sirv": "^2.0.3", - "ws": "^7.3.1" - }, - "bin": { - "webpack-bundle-analyzer": "lib/bin/analyzer.js" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/webpack-bundle-analyzer/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "license": "MIT", - "engines": { - "node": ">= 10" - } - }, - "node_modules/webpack-dev-middleware": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", - "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", - "license": "MIT", - "dependencies": { - "colorette": "^2.0.10", - "memfs": "^3.4.3", - "mime-types": "^2.1.31", - "range-parser": "^1.2.1", - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/webpack-dev-middleware/node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/webpack-dev-middleware/node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/webpack-dev-middleware/node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/webpack-dev-server": { - "version": "4.15.2", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.2.tgz", - "integrity": "sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g==", - "license": "MIT", - "dependencies": { - "@types/bonjour": "^3.5.9", - "@types/connect-history-api-fallback": "^1.3.5", - "@types/express": "^4.17.13", - "@types/serve-index": "^1.9.1", - "@types/serve-static": "^1.13.10", - "@types/sockjs": "^0.3.33", - "@types/ws": "^8.5.5", - "ansi-html-community": "^0.0.8", - "bonjour-service": "^1.0.11", - "chokidar": "^3.5.3", - "colorette": "^2.0.10", - "compression": "^1.7.4", - "connect-history-api-fallback": "^2.0.0", - "default-gateway": "^6.0.3", - "express": "^4.17.3", - "graceful-fs": "^4.2.6", - "html-entities": "^2.3.2", - "http-proxy-middleware": "^2.0.3", - "ipaddr.js": "^2.0.1", - "launch-editor": "^2.6.0", - "open": "^8.0.9", - "p-retry": "^4.5.0", - "rimraf": "^3.0.2", - "schema-utils": "^4.0.0", - "selfsigned": "^2.1.1", - "serve-index": "^1.9.1", - "sockjs": "^0.3.24", - "spdy": "^4.0.2", - "webpack-dev-middleware": "^5.3.4", - "ws": "^8.13.0" - }, - "bin": { - "webpack-dev-server": "bin/webpack-dev-server.js" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.37.0 || ^5.0.0" - }, - "peerDependenciesMeta": { - "webpack": { - "optional": true - }, - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-dev-server/node_modules/ws": { - "version": "8.18.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz", - "integrity": "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/webpack-merge": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz", - "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", - "license": "MIT", - "dependencies": { - "clone-deep": "^4.0.1", - "flat": "^5.0.2", - "wildcard": "^2.0.1" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/webpack-sources": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", - "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==", - "license": "MIT", - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/webpack/node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/webpack/node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/webpackbar": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/webpackbar/-/webpackbar-6.0.1.tgz", - "integrity": "sha512-TnErZpmuKdwWBdMoexjio3KKX6ZtoKHRVvLIU0A47R0VVBDtx3ZyOJDktgYixhoJokZTYTt1Z37OkO9pnGJa9Q==", - "license": "MIT", - "dependencies": { - "ansi-escapes": "^4.3.2", - "chalk": "^4.1.2", - "consola": "^3.2.3", - "figures": "^3.2.0", - "markdown-table": "^2.0.0", - "pretty-time": "^1.1.0", - "std-env": "^3.7.0", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=14.21.3" - }, - "peerDependencies": { - "webpack": "3 || 4 || 5" - } - }, - "node_modules/webpackbar/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/webpackbar/node_modules/markdown-table": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-2.0.0.tgz", - "integrity": "sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==", - "license": "MIT", - "dependencies": { - "repeat-string": "^1.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/webpackbar/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/webpackbar/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/websocket-driver": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", - "license": "Apache-2.0", - "dependencies": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", - "license": "Apache-2.0", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/widest-line": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", - "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==", - "license": "MIT", - "dependencies": { - "string-width": "^5.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/wildcard": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", - "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", - "license": "MIT" - }, - "node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "license": "ISC" - }, - "node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "node_modules/ws": { - "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", - "license": "MIT", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xdg-basedir": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz", - "integrity": "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/xml-js": { - "version": "1.6.11", - "resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz", - "integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==", - "license": "MIT", - "dependencies": { - "sax": "^1.2.4" - }, - "bin": { - "xml-js": "bin/cli.js" - } - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "license": "ISC" - }, - "node_modules/yocto-queue": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.1.tgz", - "integrity": "sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg==", - "license": "MIT", - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/zwitch": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", - "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - } - } -} diff --git a/HypnoScript.Dokumentation/package.json b/HypnoScript.Dokumentation/package.json deleted file mode 100644 index 100e8f8..0000000 --- a/HypnoScript.Dokumentation/package.json +++ /dev/null @@ -1,65 +0,0 @@ -{ - "name": "hypnoscript-documentation", - "version": "1.0.0", - "private": true, - "scripts": { - "docusaurus": "docusaurus", - "start": "docusaurus start", - "build": "docusaurus build", - "swizzle": "docusaurus swizzle", - "deploy": "docusaurus deploy", - "clear": "docusaurus clear", - "serve": "docusaurus serve", - "write-translations": "docusaurus write-translations", - "write-heading-ids": "docusaurus write-heading-ids", - "typecheck": "tsc" - }, - "dependencies": { - "@docusaurus/core": "^3.8.1", - "@docusaurus/preset-classic": "^3.8.1", - "@docusaurus/theme-search-algolia": "^3.8.1", - "@mdx-js/react": "^3.0.0", - "clsx": "^2.1.0", - "prism-react-renderer": "^2.3.1", - "react": "^18.2.0", - "react-dom": "^18.2.0" - }, - "devDependencies": { - "@docusaurus/module-type-aliases": "^3.8.1", - "@docusaurus/tsconfig": "^3.8.1", - "@docusaurus/types": "^3.8.1", - "typescript": "^5.3.3" - }, - "browserslist": { - "production": [ - ">0.5%", - "not dead", - "not op_mini all" - ], - "development": [ - "last 1 chrome version", - "last 1 firefox version", - "last 1 safari version" - ] - }, - "engines": { - "node": ">=18.0" - }, - "description": "Vollständige Dokumentation für HypnoScript - Die hypnotische Programmiersprache", - "keywords": [ - "hypnoscript", - "programming-language", - "documentation", - "docusaurus", - "hypnotic", - "german" - ], - "author": "HypnoScript Team", - "license": "MIT", - "repository": { - "type": "git", - "url": "https://github.com/Kink-Development-Group/hyp-runtime.git", - "directory": "HypnoScript.Dokumentation" - }, - "homepage": "https://Kink-Development-Group.github.io/hyp-runtime/" -} diff --git a/HypnoScript.Dokumentation/sidebars.js b/HypnoScript.Dokumentation/sidebars.js deleted file mode 100644 index 832a8a5..0000000 --- a/HypnoScript.Dokumentation/sidebars.js +++ /dev/null @@ -1,111 +0,0 @@ -/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ -const sidebars = { - tutorialSidebar: [ - { - type: 'doc', - id: 'intro', - label: 'Einführung', - }, - { - type: 'category', - label: 'Erste Schritte', - items: [ - 'getting-started/installation', - 'getting-started/quick-start', - 'getting-started/hello-world', - 'getting-started/cli-basics', - ], - }, - { - type: 'category', - label: 'Sprachreferenz', - items: [ - 'language-reference/syntax', - 'language-reference/variables', - 'language-reference/data-types', - 'language-reference/operators', - 'language-reference/control-flow', - 'language-reference/functions', - 'language-reference/sessions', - 'language-reference/tranceify', - 'language-reference/arrays', - 'language-reference/records', - 'language-reference/imports', - 'language-reference/assertions', - ], - }, - { - type: 'category', - label: 'Builtin-Funktionen', - items: [ - 'builtins/overview', - 'builtins/array-functions', - 'builtins/string-functions', - 'builtins/math-functions', - 'builtins/utility-functions', - 'builtins/system-functions', - 'builtins/time-date-functions', - 'builtins/statistics-functions', - 'builtins/hashing-encoding', - 'builtins/hypnotic-functions', - 'builtins/dictionary-functions', - 'builtins/file-functions', - 'builtins/network-functions', - 'builtins/validation-functions', - 'builtins/performance-functions', - ], - }, - { - type: 'category', - label: 'CLI & Tools', - items: [ - 'cli/overview', - 'cli/commands', - 'cli/configuration', - 'cli/testing', - 'cli/debugging', - 'cli/enterprise-features', - ], - }, - { - type: 'category', - label: 'Beispiele', - items: [ - 'examples/basic-examples', - 'examples/array-examples', - 'examples/string-examples', - 'examples/math-examples', - 'examples/file-examples', - 'examples/hypnotic-examples', - 'examples/advanced-examples', - ], - }, - { - type: 'category', - label: 'Entwicklung', - items: [ - 'development/architecture', - 'development/contributing', - 'development/building', - 'development/testing', - 'development/debugging', - 'development/extending', - ], - }, - { - type: 'category', - label: 'Referenz', - items: [ - 'reference/grammar', - 'reference/ast', - 'reference/interpreter', - 'reference/compiler', - 'reference/runtime', - 'reference/api', - 'changelog', - ], - }, - ], -}; - -module.exports = sidebars; diff --git a/HypnoScript.Dokumentation/sidebars.ts b/HypnoScript.Dokumentation/sidebars.ts deleted file mode 100644 index 2897139..0000000 --- a/HypnoScript.Dokumentation/sidebars.ts +++ /dev/null @@ -1,33 +0,0 @@ -import type {SidebarsConfig} from '@docusaurus/plugin-content-docs'; - -// This runs in Node.js - Don't use client-side code here (browser APIs, JSX...) - -/** - * Creating a sidebar enables you to: - - create an ordered group of docs - - render a sidebar for each doc of that group - - provide next/previous navigation - - The sidebars can be generated from the filesystem, or explicitly defined here. - - Create as many sidebars as you want. - */ -const sidebars: SidebarsConfig = { - // By default, Docusaurus generates a sidebar from the docs folder structure - tutorialSidebar: [{type: 'autogenerated', dirName: '.'}], - - // But you can create a sidebar manually - /* - tutorialSidebar: [ - 'intro', - 'hello', - { - type: 'category', - label: 'Tutorial', - items: ['tutorial-basics/create-a-document'], - }, - ], - */ -}; - -export default sidebars; diff --git a/HypnoScript.Dokumentation/src/components/HomepageFeatures/index.tsx b/HypnoScript.Dokumentation/src/components/HomepageFeatures/index.tsx deleted file mode 100644 index 9e31ed8..0000000 --- a/HypnoScript.Dokumentation/src/components/HomepageFeatures/index.tsx +++ /dev/null @@ -1,94 +0,0 @@ -import Heading from '@theme/Heading'; -import clsx from 'clsx'; -import React from 'react'; -import styles from './styles.module.css'; - -type FeatureItem = { - title: string; - description: React.JSX.Element; -}; - -const FeatureList: FeatureItem[] = [ - { - title: '🧠 Hypnotische Syntax', - description: ( - <> - Verwendet hypnotische Konzepte wie Focus,{' '} - Trance, Induce,Observe und{' '} - Relax für eine intuitive und einzigartige Programmierung. - - ), - }, - { - title: '📚 Umfangreiche Bibliothek', - description: ( - <> - Über 200+ eingebaute Funktionen für Arrays, Strings, Mathematik, - System-Operationen, Datei-Handling, Netzwerk und hypnotische - Spezialfunktionen. - - ), - }, - { - title: '🛠️ Runtime-Ready', - description: ( - <> - Vollständige CLI-Tools, Test-Framework mit Assertions, - Debugging-Unterstützung, Webserver und API-Features für professionelle - Entwicklung. - - ), - }, - { - title: '🌐 Plattformübergreifend', - description: ( - <> - Läuft auf Windows, macOS und Linux. Geschrieben in C# mit .NET für - maximale Kompatibilität und Performance. - - ), - }, - { - title: '⚡ Moderne Features', - description: ( - <> - Unterstützt Arrays, Records, Funktionen, Sessions, Imports, Assertions, - und vieles mehr für moderne Softwareentwicklung. - - ), - }, - { - title: '🤝 Open Source', - description: ( - <> - Unter MIT-Lizenz veröffentlicht. Aktive Community, regelmäßige Updates, - und Beiträge sind willkommen. - - ), - }, -]; - -function Feature({ title, description }: FeatureItem) { - return ( -
-
- {title} -

{description}

-
-
- ); -} - -export default function HomepageFeatures(): React.JSX.Element { - return ( -
-
-
- {FeatureList.map((props, idx) => ( - - ))} -
-
-
- ); -} diff --git a/HypnoScript.Dokumentation/src/components/HomepageFeatures/styles.module.css b/HypnoScript.Dokumentation/src/components/HomepageFeatures/styles.module.css deleted file mode 100644 index b248eb2..0000000 --- a/HypnoScript.Dokumentation/src/components/HomepageFeatures/styles.module.css +++ /dev/null @@ -1,11 +0,0 @@ -.features { - display: flex; - align-items: center; - padding: 2rem 0; - width: 100%; -} - -.featureSvg { - height: 200px; - width: 200px; -} diff --git a/HypnoScript.Dokumentation/src/css/custom.css b/HypnoScript.Dokumentation/src/css/custom.css deleted file mode 100644 index da1abd3..0000000 --- a/HypnoScript.Dokumentation/src/css/custom.css +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Any CSS included here will be global. The classic template - * bundles Infima by default. Infima is a CSS framework designed to - * work well for content-centric websites. - */ - -/* You can override the default Infima variables here. */ -:root { - --ifm-color-primary: #8e44ad; - --ifm-color-primary-dark: #803ea0; - --ifm-color-primary-darker: #763a95; - --ifm-color-primary-darkest: #602e78; - --ifm-color-primary-light: #9b59b6; - --ifm-color-primary-lighter: #a569bd; - --ifm-color-primary-lightest: #af7ac5; - --ifm-code-font-size: 95%; - --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); -} - -/* For readability concerns, you should choose a lighter palette in dark mode. */ -[data-theme='dark'] { - --ifm-color-primary: #a970d2; - --ifm-color-primary-dark: #9e5fd0; - --ifm-color-primary-darker: #9657c8; - --ifm-color-primary-darkest: #7c46a6; - --ifm-color-primary-light: #b581d9; - --ifm-color-primary-lighter: #bd8cde; - --ifm-color-primary-lightest: #c99ee5; - --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); -} diff --git a/HypnoScript.Dokumentation/src/pages/index.module.css b/HypnoScript.Dokumentation/src/pages/index.module.css deleted file mode 100644 index 9f71a5d..0000000 --- a/HypnoScript.Dokumentation/src/pages/index.module.css +++ /dev/null @@ -1,23 +0,0 @@ -/** - * CSS files with the .module.css suffix will be treated as CSS modules - * and scoped locally. - */ - -.heroBanner { - padding: 4rem 0; - text-align: center; - position: relative; - overflow: hidden; -} - -@media screen and (max-width: 996px) { - .heroBanner { - padding: 2rem; - } -} - -.buttons { - display: flex; - align-items: center; - justify-content: center; -} diff --git a/HypnoScript.Dokumentation/src/pages/index.tsx b/HypnoScript.Dokumentation/src/pages/index.tsx deleted file mode 100644 index 9aa4d3f..0000000 --- a/HypnoScript.Dokumentation/src/pages/index.tsx +++ /dev/null @@ -1,257 +0,0 @@ -import Link from '@docusaurus/Link'; -import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; -import HomepageFeatures from '@site/src/components/HomepageFeatures'; -import Heading from '@theme/Heading'; -import Layout from '@theme/Layout'; -import clsx from 'clsx'; -import type { ReactNode } from 'react'; - -import styles from './index.module.css'; - -function HomepageHeader() { - const { siteConfig } = useDocusaurusContext(); - return ( -
-
- - {siteConfig.title} - -

{siteConfig.tagline}

-
- - Erste Schritte - 5min ⏱️ - -
-
-
- ); -} - -export default function Home(): ReactNode { - const { siteConfig } = useDocusaurusContext(); - return ( - - -
-
-
- 🚀 Installation -

- Installiere HypnoScript plattformübergreifend mit den offiziellen - Paketmanagern oder lade die Pakete direkt von GitHub Releases - herunter. -

-
-
- Windows (winget): -
-                  winget install HypnoScript.HypnoScript
-                
-
-
- Linux (APT): -
-                  sudo apt update{`\n`}sudo apt install hypnoscript
-                
-
-
- Alle Pakete & manuelle Downloads: - - GitHub Releases - -
-
-
-
- -
-
-
-
-

- 🧠 Willkommen in der hypnotischen Welt der Programmierung -

-

- HypnoScript verbindet hypnotische Konzepte mit moderner - Softwareentwicklung. Erlebe eine einzigartige Syntax, die - sowohl intuitiv als auch mächtig ist. -

-
-
-
- -
-
-
-
-

🚀 Schnellstart

-
-
-

- Beginne in wenigen Minuten mit HypnoScript. Lerne die - Grundlagen und erstelle dein erstes Programm. -

-
-
- - Installation - -
-
-
- -
-
-
-

📚 Sprachreferenz

-
-
-

- Lerne die hypnotische Syntax kennen. Von Variablen über - Funktionen bis hin zu Sessions und Tranceify. -

-
-
- - Syntax lernen - -
-
-
- -
-
-
-

🔧 Builtin-Funktionen

-
-
-

- Entdecke über 200+ eingebaute Funktionen für Arrays, - Strings, Mathematik, System und mehr. -

-
-
- - Funktionen entdecken - -
-
-
-
- -
-
-
-
-

💡 Beispiel-Code

-
-
-
-                    {`Focus {
-    entrance {
-        observe "Willkommen bei HypnoScript!";
-    }
-
-    induce name = "Welt";
-    observe "Hallo, " + name + "!";
-
-    induce numbers = [1, 2, 3, 4, 5];
-    induce sum = SumArray(numbers);
-    observe "Summe: " + sum;
-} Relax;`}
-                  
-
-
-
- -
-
-
-

🎯 Hauptmerkmale

-
-
-
    -
  • - Hypnotische Syntax: Focus, Trance, - Induce, Observe, Relax -
  • -
  • - 200+ Builtin-Funktionen: Arrays, Strings, - Math, System, etc. -
  • -
  • - Moderne Features: Arrays, Records, - Funktionen, Sessions -
  • -
  • - Runtime-Ready: CLI, Tests, Debugging, - Deployment -
  • -
  • - Plattformübergreifend: Windows, macOS, - Linux -
  • -
  • - Open Source: MIT-Lizenz, aktive Community -
  • -
-
-
-
-
- -
-
-
-

🤝 Community & Support

-

- Werde Teil der HypnoScript-Community und erhalte Hilfe bei der - Entwicklung. -

-
- - GitHub Repository - - - Issues melden - - - Diskussionen - -
-
-
-
-
-
-
- ); -} diff --git a/HypnoScript.Dokumentation/src/pages/markdown-page.md b/HypnoScript.Dokumentation/src/pages/markdown-page.md deleted file mode 100644 index 9756c5b..0000000 --- a/HypnoScript.Dokumentation/src/pages/markdown-page.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Markdown page example ---- - -# Markdown page example - -You don't need React to write simple standalone pages. diff --git a/HypnoScript.Dokumentation/static/img/docusaurus-social-card.jpg b/HypnoScript.Dokumentation/static/img/docusaurus-social-card.jpg deleted file mode 100644 index ffcb448..0000000 Binary files a/HypnoScript.Dokumentation/static/img/docusaurus-social-card.jpg and /dev/null differ diff --git a/HypnoScript.Dokumentation/static/img/docusaurus.png b/HypnoScript.Dokumentation/static/img/docusaurus.png deleted file mode 100644 index f458149..0000000 Binary files a/HypnoScript.Dokumentation/static/img/docusaurus.png and /dev/null differ diff --git a/HypnoScript.Dokumentation/static/img/favicon.ico b/HypnoScript.Dokumentation/static/img/favicon.ico deleted file mode 100644 index c01d54b..0000000 Binary files a/HypnoScript.Dokumentation/static/img/favicon.ico and /dev/null differ diff --git a/HypnoScript.Dokumentation/static/img/undraw_docusaurus_mountain.svg b/HypnoScript.Dokumentation/static/img/undraw_docusaurus_mountain.svg deleted file mode 100644 index af961c4..0000000 --- a/HypnoScript.Dokumentation/static/img/undraw_docusaurus_mountain.svg +++ /dev/null @@ -1,171 +0,0 @@ - - Easy to Use - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/HypnoScript.Dokumentation/static/img/undraw_docusaurus_react.svg b/HypnoScript.Dokumentation/static/img/undraw_docusaurus_react.svg deleted file mode 100644 index 94b5cf0..0000000 --- a/HypnoScript.Dokumentation/static/img/undraw_docusaurus_react.svg +++ /dev/null @@ -1,170 +0,0 @@ - - Powered by React - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/HypnoScript.Dokumentation/static/img/undraw_docusaurus_tree.svg b/HypnoScript.Dokumentation/static/img/undraw_docusaurus_tree.svg deleted file mode 100644 index d9161d3..0000000 --- a/HypnoScript.Dokumentation/static/img/undraw_docusaurus_tree.svg +++ /dev/null @@ -1,40 +0,0 @@ - - Focus on What Matters - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/HypnoScript.Dokumentation/tsconfig.json b/HypnoScript.Dokumentation/tsconfig.json deleted file mode 100644 index 920d7a6..0000000 --- a/HypnoScript.Dokumentation/tsconfig.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - // This file is not used in compilation. It is here just for a nice editor experience. - "extends": "@docusaurus/tsconfig", - "compilerOptions": { - "baseUrl": "." - }, - "exclude": [".docusaurus", "build"] -} diff --git a/HypnoScript.LexerParser/AST/Nodes.cs b/HypnoScript.LexerParser/AST/Nodes.cs deleted file mode 100644 index f9e001a..0000000 --- a/HypnoScript.LexerParser/AST/Nodes.cs +++ /dev/null @@ -1,123 +0,0 @@ -namespace HypnoScript.LexerParser.AST -{ - // AST-Basisinterfaces - public interface IStatement { } - public interface IExpression { } - - // Programm-Knoten - public record ProgramNode(List Statements) : IStatement; - - // Entrance-Block am Programmanfang - public record EntranceBlockNode(List Statements) : IStatement; - - // Variablen-Deklaration - public record VarDeclNode( - string Identifier, - string? TypeName, - IExpression? Initializer, - bool FromExternal - ) : IStatement; - - // Expression Statement - public record ExpressionStatementNode(IExpression Expression) : IStatement; - - // Kontrollstrukturen - public record IfStatementNode(IExpression Condition, List ThenBranch, List? ElseBranch) : IStatement; - public record WhileStatementNode(IExpression Condition, List Body) : IStatement; - public record LoopStatementNode( - IStatement? Initializer, // z.B. induce i: number = 0; - IExpression Condition, // z.B. i < 10; - IStatement? Iteration, // z.B. i = i + 1; - List Body // Body der Schleife - ) : IStatement; - - // Break und Continue - public record SnapStatementNode() : IStatement; // break - public record SinkStatementNode() : IStatement; // continue - public record SinkToNode(string LabelName) : IStatement; // goto - - // Labels - public record LabelNode(string Name) : IStatement; - - // Block - public record BlockStatementNode(List Statements) : IStatement; - - // Funktionen - public record FunctionDeclNode( - string Name, - List Parameters, - string? ReturnType, - List Body, - bool Imperative, - bool Dominant - ) : IStatement; - - public record ParameterNode(string Name, string? TypeName); - - // Return (awaken) - public record ReturnStatementNode(IExpression? Expression) : IStatement; - - // Ein-/Ausgabe - public record ObserveStatementNode(IExpression Expression) : IStatement; - public record DriftStatementNode(IExpression Milliseconds) : IStatement; - - // Objektorientierung - Sessions (Klassen) - public record SessionDeclNode( - string Name, - List Members - ) : IStatement; - - public record SessionMemberNode( - bool IsExposed, // expose/conceal - bool IsDominant, // dominant - IStatement Declaration - ) : IStatement; - - // Strukturen - Tranceify - public record TranceifyDeclNode( - string Name, - List Members - ) : IStatement; - - // Module und Globale - public record MindLinkNode(string FileName) : IStatement; // import - public record SharedTranceVarDeclNode(string Identifier, string? TypeName, IExpression? Initializer) : IStatement; // global - - // Expression AST-Knoten - public record BinaryExpressionNode(IExpression Left, string Operator, IExpression Right) : IExpression; - public record LiteralExpressionNode(string Value, string LiteralType) : IExpression; - public record IdentifierExpressionNode(string Name) : IExpression; - public record CallExpressionNode(IExpression Callee, List Arguments) : IExpression; - public record AssignmentExpressionNode(string Identifier, IExpression Value) : IExpression; - - // Objektorientierung - Methodenaufruf und Feldzugriff - public record MethodCallExpressionNode(IExpression Target, string MethodName, List Arguments) : IExpression; - public record FieldAccessExpressionNode(IExpression Target, string FieldName) : IExpression; - - // Strukturen - Record-Literal für tranceify-Instanzen - public record RecordLiteralExpressionNode( - string TypeName, - Dictionary Fields - ) : IExpression; - - // Session-Instanziierung - public record SessionInstantiationNode( - string SessionName, - List Arguments - ) : IExpression; - - // Unary Expressions - public record UnaryExpressionNode(string Operator, IExpression Operand) : IExpression; - - // Parenthesized Expression - public record ParenthesizedExpressionNode(IExpression Expression) : IExpression; - - // Array Access - public record ArrayAccessExpressionNode(IExpression Array, IExpression Index) : IExpression; - - // Array Literal - public record ArrayLiteralExpressionNode(List Elements) : IExpression; - - // Assert Statement - public record AssertStatementNode(IExpression Condition, string? Message) : IStatement; -} diff --git a/HypnoScript.LexerParser/HypnoScript.LexerParser.csproj b/HypnoScript.LexerParser/HypnoScript.LexerParser.csproj deleted file mode 100644 index fa71b7a..0000000 --- a/HypnoScript.LexerParser/HypnoScript.LexerParser.csproj +++ /dev/null @@ -1,9 +0,0 @@ - - - - net8.0 - enable - enable - - - diff --git a/HypnoScript.LexerParser/Lexer/Lexer.cs b/HypnoScript.LexerParser/Lexer/Lexer.cs deleted file mode 100644 index a27d4da..0000000 --- a/HypnoScript.LexerParser/Lexer/Lexer.cs +++ /dev/null @@ -1,366 +0,0 @@ -using System.Text; -namespace HypnoScript.LexerParser.Lexer -{ - public class HypnoLexer - { - private readonly string _source; - private int _pos; - private int _line = 1; - private int _column = 1; - - public HypnoLexer(string source) - { - _source = source; - } - - public IEnumerable Lex() - { - Console.WriteLine("[DEBUG] Lex() aufgerufen"); - var tokens = new List(); - - while (!IsAtEnd()) - { - Console.WriteLine($"[DEBUG] Lexer-Schleife: pos={_pos}, char='{Peek()}'"); - var startPos = _pos; - var c = Advance(); - - if (char.IsWhiteSpace(c)) - { - if (c == '\n') - { - _line++; - _column = 1; - } - continue; - } - - if (char.IsLetter(c) || c == '_') - { - // Identifier oder Keyword - var ident = ReadIdentifier(c); - var tokenType = KeywordOrIdentifier(ident); - var token = new Token(tokenType, ident, _line, _column); - Console.WriteLine($"[DEBUG][Lexer] Token: {tokenType} '{ident}' @ {_line}:{_column}"); - tokens.Add(token); - } - else if (char.IsDigit(c)) - { - // Nummer - var number = ReadNumber(c); - var token = new Token(TokenType.NumberLiteral, number, _line, _column); - Console.WriteLine($"[DEBUG][Lexer] Token: {TokenType.NumberLiteral} '{number}' @ {_line}:{_column}"); - tokens.Add(token); - } - else - { - switch (c) - { - case '=': - if (Match('=')) - tokens.Add(NewToken(TokenType.DoubleEquals, "==")); - else - tokens.Add(NewToken(TokenType.Equals, "=")); - break; - case '+': - tokens.Add(NewToken(TokenType.Plus, "+")); - break; - case '-': - tokens.Add(NewToken(TokenType.Minus, "-")); - break; - case '*': - tokens.Add(NewToken(TokenType.Asterisk, "*")); - break; - case '/': - if (Match('/')) - { - // Einzeiliger Kommentar - SkipLineComment(); - } - else if (Match('*')) - { - // Mehrzeiliger Kommentar - SkipBlockComment(); - } - else - { - tokens.Add(NewToken(TokenType.Slash, "/")); - } - break; - case '%': - tokens.Add(NewToken(TokenType.Percent, "%")); - break; - case '>': - if (Match('=')) - tokens.Add(NewToken(TokenType.GreaterEqual, ">=")); - else - tokens.Add(NewToken(TokenType.Greater, ">")); - break; - case '<': - if (Match('=')) - tokens.Add(NewToken(TokenType.LessEqual, "<=")); - else - tokens.Add(NewToken(TokenType.Less, "<")); - break; - case '!': - if (Match('=')) - tokens.Add(NewToken(TokenType.NotEquals, "!=")); - else - tokens.Add(NewToken(TokenType.Bang, "!")); - break; - case '&': - if (Match('&')) - tokens.Add(NewToken(TokenType.AmpAmp, "&&")); - // ggf. else-Fehler - break; - case '|': - if (Match('|')) - tokens.Add(NewToken(TokenType.PipePipe, "||")); - break; - case ';': - tokens.Add(NewToken(TokenType.Semicolon, ";")); - break; - case ',': - tokens.Add(NewToken(TokenType.Comma, ",")); - break; - case '(': - tokens.Add(NewToken(TokenType.LParen, "(")); - break; - case ')': - tokens.Add(NewToken(TokenType.RParen, ")")); - break; - case '{': - tokens.Add(NewToken(TokenType.LBrace, "{")); - break; - case '}': - tokens.Add(NewToken(TokenType.RBrace, "}")); - break; - case '[': - tokens.Add(NewToken(TokenType.LBracket, "[")); - break; - case ']': - tokens.Add(NewToken(TokenType.RBracket, "]")); - break; - case ':': - tokens.Add(NewToken(TokenType.Colon, ":")); - break; - case '"': - var strVal = ReadString(); - var strToken = new Token(TokenType.StringLiteral, strVal, _line, _column); - Console.WriteLine($"[DEBUG][Lexer] Token: {TokenType.StringLiteral} '{strVal}' @ {_line}:{_column}"); - tokens.Add(strToken); - break; - case '.': - tokens.Add(NewToken(TokenType.Dot, ".")); - break; - default: - // Unbekanntes Zeichen -> ignorieren oder Fehler - break; - } - } - } - - tokens.Add(NewToken(TokenType.Eof, "")); - Console.WriteLine($"[DEBUG] Lex() fertig, {tokens.Count} Tokens"); - return tokens; - } - - private string ReadIdentifier(char firstChar) - { - Console.WriteLine($"[DEBUG] ReadIdentifier startet mit '{firstChar}'"); - var sb = new StringBuilder(); - sb.Append(firstChar); - - while (!IsAtEnd() && (char.IsLetterOrDigit(Peek()) || Peek() == '_')) - { - var nextChar = Peek(); - Console.WriteLine($"[DEBUG] ReadIdentifier: pos={_pos}, nextChar='{nextChar}'"); - sb.Append(Advance()); - } - - var result = sb.ToString(); - Console.WriteLine($"[DEBUG] ReadIdentifier fertig: '{result}'"); - return result; - } - - private string ReadNumber(char firstChar) - { - var sb = new StringBuilder(); - sb.Append(firstChar); - - bool hasDot = false; - - while (!IsAtEnd()) - { - if (char.IsDigit(Peek())) - { - sb.Append(Advance()); - } - else if (Peek() == '.' && !hasDot) - { - hasDot = true; - sb.Append(Advance()); - } - else - { - break; - } - } - - return sb.ToString(); - } - - private string ReadString() - { - var sb = new StringBuilder(); - while (!IsAtEnd() && Peek() != '"') - { - sb.Append(Advance()); - } - // Schluckendes " Ende - if (!IsAtEnd()) - { - Advance(); // Konsumiere das schließende Anführungszeichen - } - return sb.ToString(); - } - - private void SkipLineComment() - { - while (!IsAtEnd() && Peek() != '\n') - Advance(); - } - - private void SkipBlockComment() - { - while (!IsAtEnd()) - { - if (Peek() == '*' && PeekNext() == '/') - { - Advance(); - Advance(); - break; - } - else - { - Advance(); - } - } - } - - private TokenType KeywordOrIdentifier(string ident) - { - return ident switch - { - // Grundlegende Programmstruktur - "Focus" => TokenType.Focus, - "Relax" => TokenType.Relax, - "entrance" => TokenType.Entrance, - "deepFocus" => TokenType.DeepFocus, - - // Variablen und Deklarationen - "induce" => TokenType.Induce, - "from" => TokenType.From, - "external" => TokenType.External, - - // Kontrollstrukturen - "if" => TokenType.If, - "else" => TokenType.Else, - "while" => TokenType.While, - "loop" => TokenType.Loop, - "snap" => TokenType.Snap, - "sink" => TokenType.Sink, - "sinkTo" => TokenType.SinkTo, - - // Funktionen - "suggestion" => TokenType.Suggestion, - "imperative" => TokenType.ImperativeSuggestion, - "dominant" => TokenType.Dominant, - "awaken" => TokenType.Awaken, - "return" => TokenType.Awaken, - "call" => TokenType.Call, - - // Objektorientierung - "session" => TokenType.Session, - "constructor" => TokenType.Constructor, - "expose" => TokenType.Expose, - "conceal" => TokenType.Conceal, - - // Strukturen - "tranceify" => TokenType.Tranceify, - - // Ein-/Ausgabe - "observe" => TokenType.Observe, - "drift" => TokenType.Drift, - - // Hypnotische Operatoren - "youAreFeelingVerySleepy" => TokenType.YouAreFeelingVerySleepy, - "lookAtTheWatch" => TokenType.LookAtTheWatch, - "fallUnderMySpell" => TokenType.FallUnderMySpell, - "notSoDeep" => TokenType.NotSoDeep, - "deeplyGreater" => TokenType.DeeplyGreater, - "deeplyLess" => TokenType.DeeplyLess, - - // Module und Globale - "mindLink" => TokenType.MindLink, - "sharedTrance" => TokenType.SharedTrance, - - // Typen - "number" => TokenType.Number, - "string" => TokenType.String, - "boolean" => TokenType.Boolean, - "trance" => TokenType.Trance, - - // Boolean Literale - "true" => TokenType.True, - "false" => TokenType.False, - - "assert" => TokenType.Assert, - - _ => TokenType.Identifier - }; - } - - private char Advance() - { - var c = _source[_pos]; - _pos++; - _column++; - return c; - } - - private bool Match(char expected) - { - if (IsAtEnd()) return false; - if (_source[_pos] == expected) - { - _pos++; - _column++; - return true; - } - return false; - } - - private char Peek() => IsAtEnd() ? '\0' : _source[_pos]; - private char PeekNext() => (_pos + 1 >= _source.Length) ? '\0' : _source[_pos + 1]; - - private bool IsAtEnd() => _pos >= _source.Length; - - private Token NewToken(TokenType type, string lexeme) - { - var token = new Token(type, lexeme, _line, _column); - Console.WriteLine($"[DEBUG][NewToken] Token: {type} '{lexeme}' @ {_line}:{_column}"); - return token; - } - - // Hilfsmethode, um das nächste Wort zu peeken (ohne Whitespace zu überspringen) - private string PeekWord() - { - int pos = _pos; - while (pos < _source.Length && char.IsWhiteSpace(_source[pos])) pos++; - var sb = new StringBuilder(); - while (pos < _source.Length && (char.IsLetter(_source[pos]) || _source[pos] == '_')) - sb.Append(_source[pos++]); - return sb.ToString(); - } - } -} diff --git a/HypnoScript.LexerParser/Lexer/Token.cs b/HypnoScript.LexerParser/Lexer/Token.cs deleted file mode 100644 index b377f7a..0000000 --- a/HypnoScript.LexerParser/Lexer/Token.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace HypnoScript.LexerParser.Lexer -{ - public record Token(TokenType Type, string Lexeme, int Line, int Column); -} diff --git a/HypnoScript.LexerParser/Lexer/TokenType.cs b/HypnoScript.LexerParser/Lexer/TokenType.cs deleted file mode 100644 index 1ab1db9..0000000 --- a/HypnoScript.LexerParser/Lexer/TokenType.cs +++ /dev/null @@ -1,109 +0,0 @@ -public enum TokenType -{ - // Grundlegende Programmstruktur - Focus, - Relax, - Entrance, - DeepFocus, - - // Variablen und Deklarationen - Induce, - From, - External, - - // Kontrollstrukturen - If, - Else, - While, - Loop, - Snap, // break - Sink, // continue - SinkTo, // goto - - // Funktionen - Suggestion, - ImperativeSuggestion, - DominantSuggestion, - Awaken, // return - Call, - - // Objektorientierung - Session, - Constructor, - Expose, // public - Conceal, // private - Dominant, // static - - // Strukturen - Tranceify, - - // Ein-/Ausgabe - Observe, - Drift, - - // Hypnotische Operatoren - YouAreFeelingVerySleepy, // == - LookAtTheWatch, // > - FallUnderMySpell, // < - NotSoDeep, // != - DeeplyGreater, // >= - DeeplyLess, // <= - - // Module und Globale - MindLink, // import - SharedTrance, // global - - // Labels - Label, - - // Standard Operatoren - DoubleEquals, // == - NotEquals, // != - Greater, - GreaterEqual, // >= - Less, - LessEqual, // <= - Plus, - Minus, - Asterisk, - Slash, - Percent, - Bang, // ! - AmpAmp, // && - PipePipe, // || - - // Literale und Bezeichner - Identifier, - NumberLiteral, - StringLiteral, - BooleanLiteral, - - // Typen - Number, - String, - Boolean, - Trance, - - // Boolean Literale - True, - False, - - // Trennzeichen und Klammern - LParen, // ( - RParen, // ) - LBrace, // { - RBrace, // } - LBracket, // [ - RBracket, // ] - Comma, - Colon, // : - Semicolon, // ; - Dot, // . - Equals, // = - - // Ende der Datei - Eof, - - // Assert-Statement - Assert -} diff --git a/HypnoScript.LexerParser/Parser/HypnoParser.cs b/HypnoScript.LexerParser/Parser/HypnoParser.cs deleted file mode 100644 index 9ad6d04..0000000 --- a/HypnoScript.LexerParser/Parser/HypnoParser.cs +++ /dev/null @@ -1,851 +0,0 @@ -using HypnoScript.LexerParser.AST; -using HypnoScript.LexerParser.Lexer; - -namespace HypnoScript.LexerParser.Parser -{ - public class HypnoParser - { - private readonly List _tokens; - private int _current; - - public HypnoParser(IEnumerable tokens) - { - _tokens = tokens.ToList(); - } - - public ProgramNode ParseProgram() - { - Console.WriteLine($"[DEBUG] Start ParseProgram, current token: {Peek().Type} '{Peek().Lexeme}'"); - // Sicherstellen, dass das Programm mit "Focus" beginnt - if (!Check(TokenType.Focus)) - throw new Exception("Program must start with 'Focus'."); - Advance(); // consume Focus - - var statements = ParseBlockStatements(); - - Console.WriteLine($"[DEBUG] Nach Block, current token: {Peek().Type} '{Peek().Lexeme}'"); - if (!Check(TokenType.Relax)) - throw new Exception("Program must end with 'Relax'."); - Advance(); // consume Relax - - return new ProgramNode(statements); - } - - private IStatement ParseStatement() - { - if (Match(TokenType.Induce)) - return ParseVarDecl(); - - if (Match(TokenType.If)) - return ParseIfStatement(); - - if (Match(TokenType.While)) - return ParseWhileStatement(); - - if (Match(TokenType.Loop)) - return ParseLoopStatement(); - - if (Match(TokenType.Suggestion)) - return ParseFunctionDeclaration(); - - // imperative suggestion - if (Match(TokenType.ImperativeSuggestion)) - { - if (Match(TokenType.Suggestion)) - return ParseFunctionDeclaration(); - else - throw new Exception("Expected 'suggestion' after 'imperative'."); - } - - // dominant suggestion - if (Match(TokenType.DominantSuggestion)) - { - if (Match(TokenType.Suggestion)) - return ParseFunctionDeclaration(); - else - throw new Exception("Expected 'suggestion' after 'dominant'."); - } - - if (Match(TokenType.Session)) - return ParseSessionDeclaration(); - - if (Match(TokenType.Tranceify)) - return ParseTranceifyDeclaration(); - - if (Match(TokenType.Observe)) - return ParseObserveStatement(); - - if (Match(TokenType.Drift)) - return ParseDriftStatement(); - - if (Match(TokenType.Awaken)) - return ParseReturnStatement(); - - if (Match(TokenType.Snap)) - { - Consume(TokenType.Semicolon, "Expect ';' after snap."); - return new SnapStatementNode(); - } - if (Match(TokenType.Sink)) - { - Consume(TokenType.Semicolon, "Expect ';' after sink."); - return new SinkStatementNode(); - } - if (Match(TokenType.MindLink)) - { - var fileToken = Consume(TokenType.StringLiteral, "Expected string literal after mindLink."); - Consume(TokenType.Semicolon, "Expect ';' after mindLink statement."); - return new MindLinkNode(fileToken.Lexeme); - } - if (Match(TokenType.SharedTrance)) - { - var nameToken = Consume(TokenType.Identifier, "Expect identifier after 'sharedTrance'."); - string? typeName = null; - IExpression? initializer = null; - if (Match(TokenType.Colon)) - { - var typeToken = Consume(TokenType.Identifier, "Expect type name after ':' in sharedTrance."); - typeName = typeToken.Lexeme; - } - if (Match(TokenType.Equals)) - { - initializer = ParseExpression(); - } - Consume(TokenType.Semicolon, "Expect ';' after sharedTrance declaration."); - return new SharedTranceVarDeclNode(nameToken.Lexeme, typeName, initializer); - } - if (Match(TokenType.Label)) - { - var labelName = Previous().Lexeme; - return new LabelNode(labelName); - } - if (Match(TokenType.SinkTo)) - { - var labelToken = Consume(TokenType.Identifier, "Expected label name after 'sinkTo'."); - Consume(TokenType.Semicolon, "Expect ';' after sinkTo statement."); - return new SinkToNode(labelToken.Lexeme); - } - if (Match(TokenType.Assert)) - { - Consume(TokenType.LParen, "Expect '(' after 'assert'."); - var condition = ParseExpression(); - Consume(TokenType.RParen, "Expect ')' after assert condition."); - string? message = null; - if (Check(TokenType.StringLiteral)) - { - message = Advance().Lexeme; - } - Consume(TokenType.Semicolon, "Expect ';' after assert statement."); - return new AssertStatementNode(condition, message); - } - // Fallback: Expression Statement - var expr = ParseExpression(); - Consume(TokenType.Semicolon, "Expect ';' after expression."); - return new ExpressionStatementNode(expr); - } - - private IStatement ParseDriftStatement() - { - // drift(expression); - Consume(TokenType.LParen, "Expect '(' after 'drift'."); - var milliseconds = ParseExpression(); - Consume(TokenType.RParen, "Expect ')' after drift expression."); - Consume(TokenType.Semicolon, "Expect ';' after drift statement."); - return new DriftStatementNode(milliseconds); - } - - // Neue Methode: Loop-Statement parsen - private IStatement ParseLoopStatement() - { - // Annahme: "loop" wurde bereits gematcht. - // Erwarte: '(' [Initialisierung] ';' Expression ';' Expression ')' BlockStatement. - Consume(TokenType.LParen, "Expected '(' after 'loop'."); IStatement? initializer = null; - if (!Check(TokenType.Semicolon)) - { - // Check if it's a variable declaration starting with 'induce' - if (Check(TokenType.Induce)) - { - Advance(); // consume 'induce' - initializer = ParseVarDeclWithoutSemicolon(); // Spezielle Version ohne Semikolon - } - else - { - // Expression statement - var expr = ParseExpression(); - initializer = new ExpressionStatementNode(expr); - } - } - Consume(TokenType.Semicolon, "Expected ';' after loop initializer."); - - var condition = ParseExpression(); - Consume(TokenType.Semicolon, "Expected ';' after loop condition."); - - IExpression iteration = ParseExpression(); - Consume(TokenType.RParen, "Expected ')' after loop iteration."); - - var body = ParseBlockStatements(); - return new LoopStatementNode(initializer, condition, new ExpressionStatementNode(iteration), body); - } - - // Spezielle Version von ParseVarDecl ohne abschließendes Semikolon (für Loop-Statements) - private IStatement ParseVarDeclWithoutSemicolon() - { - // 'induce x: number = 5' (ohne Semikolon) - var nameToken = Consume(TokenType.Identifier, "Expect identifier after 'induce'."); - - string? typeName = null; - bool fromExternal = false; - IExpression? initializer = null; - - if (Match(TokenType.Colon)) - { - // parse type - akzeptiere Identifier oder Typ-Keywords - if (Match(TokenType.Number) || Match(TokenType.String) || Match(TokenType.Boolean)) - { - typeName = Previous().Lexeme; - } - else - { - var typeToken = Consume(TokenType.Identifier, "Expect type name after ':'."); - typeName = typeToken.Lexeme; - } - } - - if (Match(TokenType.Equals)) - { - // parse initializer - initializer = ParseExpression(); - } - else if (Match(TokenType.From)) - { - // parse 'from external' - if (!Match(TokenType.External)) - throw new Exception("Expected 'external' after 'from'."); - fromExternal = true; - } - - // Kein Semikolon hier - das wird vom aufrufenden Code erwartet - return new VarDeclNode(nameToken.Lexeme, typeName, initializer, fromExternal); - } - - // Neue Methode: Funktionsdeklaration parsen - private IStatement ParseFunctionDeclaration() - { - // Erwartet: (suggestion | imperative suggestion | dominant suggestion) (Identifier | Constructor) '(' [ParameterList] ')' [':' Type] BlockStatement. - // Das Schlüsselwort wurde bereits gematcht, wir speichern es zur Unterscheidung. - string funcKeyword = Previous().Lexeme; - - // Accept either function name (Identifier) or constructor keyword - Token nameToken; - if (Check(TokenType.Identifier)) - { - nameToken = Advance(); - } - else if (Check(TokenType.Constructor)) - { - nameToken = Advance(); - } - else - { - throw new Exception("Expected function name or 'constructor' after suggestion keyword."); - } - Consume(TokenType.LParen, "Expected '(' after function name."); - var parameters = new List(); - if (!Check(TokenType.RParen)) - { - do - { - var paramName = Consume(TokenType.Identifier, "Expected parameter name.").Lexeme; - string? typeName = null; if (Match(TokenType.Colon)) - { - var typeToken = ConsumeTypeToken("Expected type name after ':' in parameter list."); - typeName = typeToken.Lexeme; - } - parameters.Add(new ParameterNode(paramName, typeName)); - } while (Match(TokenType.Comma)); - } - Consume(TokenType.RParen, "Expected ')' after parameter list."); - - string? returnType = null; if (Match(TokenType.Colon)) - { - var typeToken = ConsumeTypeToken("Expected return type following ':'."); - returnType = typeToken.Lexeme; - } - - var body = ParseBlockStatements(); - - // Bestimme die Flags basierend auf den vorherigen Tokens - bool imperative = funcKeyword == "imperative" || funcKeyword.Contains("imperative"); - bool dominant = funcKeyword == "dominant" || funcKeyword.Contains("dominant"); - - return new FunctionDeclNode(nameToken.Lexeme, parameters, returnType, body, imperative, dominant); - } - - // Neue Methode: Session-Deklaration parsen - private IStatement ParseSessionDeclaration() - { - // Erwartet: 'session' Identifier '{' { SessionMember } '}' - var nameToken = Consume(TokenType.Identifier, "Expected session name after 'session'.").Lexeme; - Consume(TokenType.LBrace, "Expected '{' after session name."); - var members = new List(); - while (!Check(TokenType.RBrace) && !IsAtEnd()) - { - members.Add(ParseSessionMember()); - } - Consume(TokenType.RBrace, "Expected '}' to close session declaration."); - return new SessionDeclNode(nameToken, members); - } - - private SessionMemberNode ParseSessionMember() - { - bool isExposed = false; - bool isDominant = false; - - // Parse expose/conceal - if (Match(TokenType.Expose)) - isExposed = true; - else if (Match(TokenType.Conceal)) - isExposed = false; - - // Parse dominant - if (Match(TokenType.Dominant)) - isDominant = true; // Parse the actual declaration - IStatement declaration; - if (Match(TokenType.Induce)) - { - declaration = ParseVarDecl(); - } - else if (Match(TokenType.Suggestion)) - { - declaration = ParseFunctionDeclaration(); - } - else if (Check(TokenType.Identifier)) - { - // Parse property declaration (e.g., name: string;) - declaration = ParsePropertyDeclaration(); - } - else - { - throw new Exception("Expected 'induce', 'suggestion', or property declaration in session member."); - } - - return new SessionMemberNode(isExposed, isDominant, declaration); - } - - // Neue Methode: Tranceify-Deklaration parsen - private IStatement ParseTranceifyDeclaration() - { - // Erwartet: 'tranceify' Identifier '{' { VarDeclaration } '}' - var nameToken = Consume(TokenType.Identifier, "Expected tranceify name after 'tranceify'.").Lexeme; - Consume(TokenType.LBrace, "Expected '{' after tranceify name."); - var members = new List(); - while (!Check(TokenType.RBrace) && !IsAtEnd()) - { - // Wir parsen jede VarDecl innerhalb des Tranceify-Blocks und casten explizit zu VarDeclNode. - IStatement stmt = ParseVarDecl(); - if (stmt is VarDeclNode varDecl) - { - members.Add(varDecl); - } - else - { - throw new Exception("Expected variable declaration inside tranceify block."); - } - } - Consume(TokenType.RBrace, "Expected '}' to close tranceify declaration."); - return new TranceifyDeclNode(nameToken, members); - } - - private IStatement ParseVarDecl() - { - // 'induce x: number = 5;' oder 'induce y from external;' - var nameToken = Consume(TokenType.Identifier, "Expect identifier after 'induce'."); - - string? typeName = null; - bool fromExternal = false; - IExpression? initializer = null; - - if (Match(TokenType.Colon)) - { - // parse type - akzeptiere Identifier oder Typ-Keywords - if (Match(TokenType.Number) || Match(TokenType.String) || Match(TokenType.Boolean)) - { - typeName = Previous().Lexeme; - } - else - { - var typeToken = Consume(TokenType.Identifier, "Expect type name after ':'."); - typeName = typeToken.Lexeme; - } - } - - if (Match(TokenType.Equals)) - { - // parse initializer - initializer = ParseExpression(); - } - else if (Match(TokenType.From)) - { - // parse 'from external' - if (!Match(TokenType.External)) - throw new Exception("Expected 'external' after 'from'."); - fromExternal = true; - } - - Consume(TokenType.Semicolon, "Expect ';' after variable declaration."); - - return new VarDeclNode(nameToken.Lexeme, typeName, initializer, fromExternal); - } - - private IStatement ParseIfStatement() - { - // if ( expr ) { ... } else { ... } - Consume(TokenType.LParen, "Expect '(' after 'if'."); - var condition = ParseExpression(); - Consume(TokenType.RParen, "Expect ')' after if condition."); - - var thenBlock = ParseBlockStatements(); - - List? elseBlock = null; - if (Match(TokenType.Else)) - { - if (Check(TokenType.If)) - { - Advance(); // consume 'if' - var elseIfNode = ParseIfStatement(); - // else-if als Block mit einem IfStatementNode - elseBlock = new List { elseIfNode }; - } - else - { - elseBlock = ParseBlockStatements(); - } - } - - return new IfStatementNode(condition, thenBlock, elseBlock); - } - - private IStatement ParseWhileStatement() - { - Consume(TokenType.LParen, "Expect '(' after 'while'."); - var condition = ParseExpression(); - Consume(TokenType.RParen, "Expect ')' after condition."); - - var body = ParseBlockStatements(); - - return new WhileStatementNode(condition, body); - } - - private IStatement ParseObserveStatement() - { - // observe expression ; - var expr = ParseExpression(); - Consume(TokenType.Semicolon, "Expect ';' after observe expression."); - return new ObserveStatementNode(expr); - } - - private IStatement ParseReturnStatement() - { - // awaken ; - if (!Check(TokenType.Semicolon)) - { - var expr = ParseExpression(); - Consume(TokenType.Semicolon, "Expect ';' after return expression."); - return new ReturnStatementNode(expr); - } - else - { - // awaken ; - Advance(); // consume semicolon - return new ReturnStatementNode(null); - } - } - - private List ParseBlockStatements() - { - Console.WriteLine($"[DEBUG] Enter Block, current token: {Peek().Type} '{Peek().Lexeme}'"); - if (Match(TokenType.DeepFocus)) - { - Consume(TokenType.LBrace, "Expect '{' after 'deepFocus'."); - } - else if (!Match(TokenType.LBrace)) - { - throw new Exception("Expect '{' to start block."); - } - - var stmts = new List(); - while (!Check(TokenType.RBrace) && !IsAtEnd()) - { - Console.WriteLine($"[DEBUG] Block loop, current token: {Peek().Type} '{Peek().Lexeme}'"); - if (Match(TokenType.Entrance)) - { - stmts.Add(ParseEntranceBlock()); - } - else - { - stmts.Add(ParseStatement()); - } - } - - Console.WriteLine($"[DEBUG] Leave Block, current token: {Peek().Type} '{Peek().Lexeme}'"); - Consume(TokenType.RBrace, "Expect '}' to end block."); - return stmts; - } - - // --------------------- - // Expressions - // --------------------- - - private IExpression ParseExpression() - { - return ParseAssignment(); - } - private IExpression ParseAssignment() - { - var expr = ParseEquality(); - - if (Match(TokenType.Equals)) - { - var equals = Previous(); - var value = ParseAssignment(); - - if (expr is IdentifierExpressionNode) - { - var name = ((IdentifierExpressionNode)expr).Name; - return new AssignmentExpressionNode(name, value); - } - else if (expr is FieldAccessExpressionNode fieldAccess) - { - // For field access like this.property, we need a special assignment node - // For now, we'll create a special identifier that represents the field access - // The interpreter will need to handle this specially - var target = fieldAccess.Target; - var fieldName = fieldAccess.FieldName; - - // Create a compound identifier for field access assignments - if (target is IdentifierExpressionNode targetId && targetId.Name == "this") - { - return new AssignmentExpressionNode($"this.{fieldName}", value); - } - else - { - throw new Exception("Complex field access assignments not yet supported."); - } - } - - throw new Exception("Invalid assignment target."); - } - - return expr; - } - - private IExpression ParseEquality() - { - var expr = ParseComparison(); - - while (Match(TokenType.DoubleEquals) || Match(TokenType.NotEquals) || - Match(TokenType.YouAreFeelingVerySleepy) || Match(TokenType.NotSoDeep)) - { - var op = Previous().Lexeme; - - // Map Synonyme - if (Previous().Type.Equals(TokenType.YouAreFeelingVerySleepy)) - op = "=="; - if (Previous().Type.Equals(TokenType.NotSoDeep)) - op = "!="; - - var right = ParseComparison(); - expr = new BinaryExpressionNode(expr, op, right); - } - - return expr; - } - - private IExpression ParseComparison() - { - var expr = ParseTerm(); - - while (Match(TokenType.Greater) || Match(TokenType.GreaterEqual) || - Match(TokenType.Less) || Match(TokenType.LessEqual) || - Match(TokenType.LookAtTheWatch) || Match(TokenType.FallUnderMySpell) || - Match(TokenType.DeeplyGreater) || Match(TokenType.DeeplyLess)) - { - var op = Previous().Lexeme; - if (Previous().Type.Equals(TokenType.LookAtTheWatch)) - op = ">"; - if (Previous().Type.Equals(TokenType.FallUnderMySpell)) - op = "<"; - if (Previous().Type.Equals(TokenType.DeeplyGreater)) - op = ">="; - if (Previous().Type.Equals(TokenType.DeeplyLess)) - op = "<="; - - var right = ParseTerm(); - expr = new BinaryExpressionNode(expr, op, right); - } - - return expr; - } - - private IExpression ParseTerm() - { - var expr = ParseFactor(); - - while (Match(TokenType.Plus) || Match(TokenType.Minus)) - { - var op = Previous().Lexeme; - var right = ParseFactor(); - expr = new BinaryExpressionNode(expr, op, right); - } - return expr; - } - - private IExpression ParseFactor() - { - var expr = ParseUnary(); - - while (Match(TokenType.Asterisk) || Match(TokenType.Slash) || Match(TokenType.Percent)) - { - var op = Previous().Lexeme; - var right = ParseUnary(); - expr = new BinaryExpressionNode(expr, op, right); - } - return expr; - } - - private IExpression ParseUnary() - { - if (Match(TokenType.Bang) || Match(TokenType.Minus) || Match(TokenType.Plus)) - { - var op = Previous().Lexeme; - var right = ParseUnary(); - // in unserem AST nicht extra, wir machen es als "BinaryExpressionNode(null, op, right)" - // -> oder ein "UnaryExpressionNode" - return new BinaryExpressionNode( - new LiteralExpressionNode("0", "number"), op, right); - // unsauber, aber symbolisch - } - return ParsePrimary(); - } - - private IExpression ParsePrimary() - { - if (Match(TokenType.NumberLiteral)) - return new LiteralExpressionNode(Previous().Lexeme, "number"); - - if (Match(TokenType.StringLiteral)) - return new LiteralExpressionNode(Previous().Lexeme, "string"); - - if (Match(TokenType.True) || Match(TokenType.False)) - return new LiteralExpressionNode(Previous().Lexeme, "boolean"); - - if (Match(TokenType.Identifier)) - { - var name = Previous().Lexeme; - - // Session-Instanziierung: Identifier( ... ) - if (Match(TokenType.LParen)) - { - var args = new List(); - if (!Check(TokenType.RParen)) - { - do - { - args.Add(ParseExpression()); - } while (Match(TokenType.Comma)); - } - Consume(TokenType.RParen, "Expect ')' after session arguments."); - return new SessionInstantiationNode(name, args); - } - - // Record-Literal: Identifier gefolgt von '{' - if (Match(TokenType.LBrace)) - { - var fields = new Dictionary(); - while (!Check(TokenType.RBrace) && !IsAtEnd()) - { - var fieldName = Consume(TokenType.Identifier, $"Expected field name in record literal for {name}.").Lexeme; - Consume(TokenType.Colon, "Expected ':' after field name in record literal."); - var fieldExpr = ParseExpression(); - fields[fieldName] = fieldExpr; - if (!Check(TokenType.RBrace)) - { - Consume(TokenType.Comma, "Expected ',' between fields in record literal."); - } - } - Consume(TokenType.RBrace, "Expected '}' to close record literal."); - return new RecordLiteralExpressionNode(name, fields); - } - - // Normale Identifier - IExpression currentExpr = new IdentifierExpressionNode(name); - - // Feldzugriff und Methodenaufrufe: .field oder .method( ... ) - while (Match(TokenType.Dot)) - { - var memberName = Consume(TokenType.Identifier, "Expected member name after '.'").Lexeme; - - // Methodenaufruf: .method( ... ) - if (Match(TokenType.LParen)) - { - var args = new List(); - if (!Check(TokenType.RParen)) - { - do - { - args.Add(ParseExpression()); - } while (Match(TokenType.Comma)); - } - Consume(TokenType.RParen, "Expect ')' after method arguments."); - currentExpr = new MethodCallExpressionNode(currentExpr, memberName, args); - } - else - { - // Feldzugriff: .field - currentExpr = new FieldAccessExpressionNode(currentExpr, memberName); - } - } - - // Array-Zugriffe: array[index] - while (Match(TokenType.LBracket)) - { - var index = ParseExpression(); - Consume(TokenType.RBracket, "Expect ']' after array index."); - currentExpr = new ArrayAccessExpressionNode(currentExpr, index); - } - - return currentExpr; - } - - if (Match(TokenType.LParen)) - { - var parenExpr = ParseExpression(); - Consume(TokenType.RParen, "Expect ')' after group expression."); - return new ParenthesizedExpressionNode(parenExpr); - } - - // Array-Literal: [ expr1, expr2, ... ] - if (Match(TokenType.LBracket)) - { - var elements = new List(); - if (!Check(TokenType.RBracket)) - { - do - { - elements.Add(ParseExpression()); - } while (Match(TokenType.Comma)); - } - Consume(TokenType.RBracket, "Expect ']' to close array literal."); - return new ArrayLiteralExpressionNode(elements); - } - - throw new Exception($"Unexpected token {Peek().Type} at line {Peek().Line}."); - } - - // Hilfsfunktionen: - private bool Match(params TokenType[] types) - { - foreach (var t in types) - { - if (Check(t)) - { - Advance(); - return true; - } - } - return false; - } - - private bool MatchKeyword(string keyword) - { - if (Check(TokenType.Identifier) && Peek().Lexeme == keyword) - { - Advance(); - return true; - } - return false; - } - - private Token Consume(TokenType type, string errorMessage) - { - if (Check(type)) return Advance(); - throw new Exception(errorMessage + $" Found {Peek().Type}."); - } - - private bool Check(TokenType type) - { - if (IsAtEnd()) return false; - return Peek().Type.Equals(type); - } - - private Token Advance() - { - if (!IsAtEnd()) _current++; - return Previous(); - } - - private bool IsAtEnd() => Peek().Type.Equals(TokenType.Eof); - - private Token Peek() => _tokens[_current]; - private Token Previous() => _tokens[_current - 1]; - - private EntranceBlockNode ParseEntranceBlock() - { - // Erwartet: entrance { ... } - Consume(TokenType.LBrace, "Expected '{' after 'entrance'."); - var stmts = new List(); - while (!Check(TokenType.RBrace) && !IsAtEnd()) - { - stmts.Add(ParseStatement()); - } - Consume(TokenType.RBrace, "Expected '}' to close entrance block."); - return new EntranceBlockNode(stmts); - } - // Neue Methode: Eigenschaftsdeklaration parsen (für Session-Member) - private IStatement ParsePropertyDeclaration() - { - // 'name: string;' oder 'age: number;' - var nameToken = Consume(TokenType.Identifier, "Expect property name."); - - string? typeName = null; - IExpression? initializer = null; - - if (Match(TokenType.Colon)) - { - // parse type - akzeptiere Identifier oder Typ-Keywords - if (Match(TokenType.Number) || Match(TokenType.String) || Match(TokenType.Boolean)) - { - typeName = Previous().Lexeme; - } - else - { - var typeToken = Consume(TokenType.Identifier, "Expect type name after ':'."); - typeName = typeToken.Lexeme; - } - } - - if (Match(TokenType.Equals)) - { - // parse initializer - initializer = ParseExpression(); - } - - Consume(TokenType.Semicolon, "Expect ';' after property declaration."); - - return new VarDeclNode(nameToken.Lexeme, typeName, initializer, false); - } - - private Token ConsumeTypeToken(string errorMessage) - { - if (Check(TokenType.Identifier) || - Check(TokenType.String) || - Check(TokenType.Number) || - Check(TokenType.Boolean) || - Check(TokenType.Trance)) - { - return Advance(); - } - throw new Exception(errorMessage + $" Found {Peek().Type}."); - } - } -} diff --git a/HypnoScript.Runtime.Tests/ArrayBuiltinsTests.cs b/HypnoScript.Runtime.Tests/ArrayBuiltinsTests.cs deleted file mode 100644 index 5c2fff0..0000000 --- a/HypnoScript.Runtime.Tests/ArrayBuiltinsTests.cs +++ /dev/null @@ -1,62 +0,0 @@ -using Xunit; -using HypnoScript.Runtime.Builtins; - -namespace HypnoScript.Runtime.Tests -{ - public class ArrayBuiltinsTests - { - [Fact] - public void ArrayLength_Works() - { - var arr = new object[] { 1, 2, 3 }; - Assert.Equal(3, ArrayBuiltins.ArrayLength(arr)); - } - - [Fact] - public void ArrayGet_Works_And_Errors() - { - var arr = new object[] { "a", "b" }; - Assert.Equal("a", ArrayBuiltins.ArrayGet(arr, 0)); - Assert.Null(ArrayBuiltins.ArrayGet(arr, 2)); // out of bounds - Assert.Null(ArrayBuiltins.ArrayGet(null, 0)); // null - } - - [Fact] - public void ArraySet_Works_And_Errors() - { - var arr = new object[] { 1, 2 }; - ArrayBuiltins.ArraySet(arr, 1, 99); - Assert.Equal(99, arr[1]); - ArrayBuiltins.ArraySet(arr, 2, 5); // out of bounds, should not throw - ArrayBuiltins.ArraySet(null, 0, 5); // null, should not throw - } - - [Fact] - public void ArraySlice_Works_And_Errors() - { - var arr = new object[] { 1, 2, 3, 4 }; - var slice = ArrayBuiltins.ArraySlice(arr, 1, 2); - Assert.Equal(new object[] { 2, 3 }, slice); - Assert.Empty(ArrayBuiltins.ArraySlice(arr, 3, 5)); // out of bounds - Assert.Empty(ArrayBuiltins.ArraySlice(null, 0, 1)); // null - } - - [Fact] - public void ArrayConcat_Works() - { - var arr1 = new object[] { 1, 2 }; - var arr2 = new object[] { 3, 4 }; - var result = ArrayBuiltins.ArrayConcat(arr1, arr2); - Assert.Equal(new object[] { 1, 2, 3, 4 }, result); - } - - [Fact] - public void ArrayIndexOf_And_Contains_Works() - { - var arr = new object[] { "x", "y", "z" }; - Assert.Equal(1, ArrayBuiltins.ArrayIndexOf(arr, "y")); - Assert.True(ArrayBuiltins.ArrayContains(arr, "z")); - Assert.False(ArrayBuiltins.ArrayContains(arr, "a")); - } - } -} diff --git a/HypnoScript.Runtime.Tests/MathBuiltinsTests.cs b/HypnoScript.Runtime.Tests/MathBuiltinsTests.cs deleted file mode 100644 index e7d2f43..0000000 --- a/HypnoScript.Runtime.Tests/MathBuiltinsTests.cs +++ /dev/null @@ -1,74 +0,0 @@ -using Xunit; -using HypnoScript.Runtime.Builtins; - -namespace HypnoScript.Runtime.Tests -{ - public class MathBuiltinsTests - { - [Fact] - public void Abs_Works() - { - Assert.Equal(5, MathBuiltins.Abs(-5)); - Assert.Equal(5, MathBuiltins.Abs(5)); - } - - [Fact] - public void Sin_Cos_Tan_Works() - { - Assert.Equal(0, MathBuiltins.Sin(0), 5); - Assert.Equal(1, MathBuiltins.Sin(90), 5); - Assert.Equal(0, MathBuiltins.Cos(90), 5); - Assert.Equal(1, MathBuiltins.Cos(0), 5); - Assert.Equal(0, MathBuiltins.Tan(0), 5); - } - - [Fact] - public void Sqrt_Works() - { - Assert.Equal(3, MathBuiltins.Sqrt(9), 5); - } - - [Fact] - public void Pow_Works() - { - Assert.Equal(8, MathBuiltins.Pow(2, 3), 5); - } - - [Fact] - public void Floor_Ceiling_Round_Works() - { - Assert.Equal(1, MathBuiltins.Floor(1.9)); - Assert.Equal(2, MathBuiltins.Ceiling(1.1)); - Assert.Equal(2, MathBuiltins.Round(1.5)); - } - - [Fact] - public void Log_Log10_Exp_Works() - { - Assert.Equal(1, MathBuiltins.Log(Math.E), 5); - Assert.Equal(2, MathBuiltins.Log10(100), 5); - Assert.Equal(Math.E, MathBuiltins.Exp(1), 5); - } - - [Fact] - public void Max_Min_Works() - { - Assert.Equal(5, MathBuiltins.Max(5, 3)); - Assert.Equal(3, MathBuiltins.Min(5, 3)); - } - - [Fact] - public void Random_ReturnsValueInRange() - { - var value = MathBuiltins.Random(); - Assert.InRange(value, 0, 1); - } - - [Fact] - public void RandomInt_ReturnsValueInRange() - { - var value = MathBuiltins.RandomInt(1, 10); - Assert.InRange(value, 1, 10); - } - } -} diff --git a/HypnoScript.Runtime.Tests/NetworkBuiltinsTests.cs b/HypnoScript.Runtime.Tests/NetworkBuiltinsTests.cs deleted file mode 100644 index 23b5fc7..0000000 --- a/HypnoScript.Runtime.Tests/NetworkBuiltinsTests.cs +++ /dev/null @@ -1,66 +0,0 @@ -using Xunit; -using HypnoScript.Runtime.Builtins; - -namespace HypnoScript.Runtime.Tests -{ - public class NetworkBuiltinsTests - { - [Fact] - public void IsValidEmail_Works() - { - Assert.True(NetworkBuiltins.IsValidEmail("test@example.com")); - Assert.False(NetworkBuiltins.IsValidEmail("invalid-email")); - } - - [Fact] - public void IsValidUrl_Works() - { - Assert.True(NetworkBuiltins.IsValidUrl("https://example.com")); - Assert.False(NetworkBuiltins.IsValidUrl("not a url")); - } - - [Fact] - public void IsValidIPAddress_Works() - { - Assert.True(NetworkBuiltins.IsValidIPAddress("127.0.0.1")); - Assert.False(NetworkBuiltins.IsValidIPAddress("notanip")); - } - - [Fact] - public void IsValidPort_Works() - { - Assert.True(NetworkBuiltins.IsValidPort(80)); - Assert.False(NetworkBuiltins.IsValidPort(70000)); - } - - [Fact] - public void UrlEncodeDecode_Works() - { - var encoded = NetworkBuiltins.UrlEncode("a b"); - Assert.Equal("a+b", encoded); - Assert.Equal("a b", NetworkBuiltins.UrlDecode(encoded)); - } - - [Fact] - public void HtmlEncodeDecode_Works() - { - var encoded = NetworkBuiltins.HtmlEncode(""); - Assert.Equal("<b>", encoded); - Assert.Equal("", NetworkBuiltins.HtmlDecode(encoded)); - } - - [Fact] - public void ExtractDomain_And_Path_Works() - { - Assert.Equal("example.com", NetworkBuiltins.ExtractDomain("https://example.com/test")); - Assert.Equal("/test", NetworkBuiltins.ExtractPath("https://example.com/test")); - } - - [Fact] - public void IsLocalhost_Works() - { - Assert.True(NetworkBuiltins.IsLocalhost("http://localhost:8080")); - Assert.False(NetworkBuiltins.IsLocalhost("https://example.com")); - } - } -} diff --git a/HypnoScript.Runtime.Tests/StringBuiltinsTests.cs b/HypnoScript.Runtime.Tests/StringBuiltinsTests.cs deleted file mode 100644 index 9e8911e..0000000 --- a/HypnoScript.Runtime.Tests/StringBuiltinsTests.cs +++ /dev/null @@ -1,71 +0,0 @@ -using Xunit; -using HypnoScript.Runtime.Builtins; - -namespace HypnoScript.Runtime.Tests -{ - public class StringBuiltinsTests - { - [Fact] - public void Length_Works() - { - Assert.Equal(4, StringBuiltins.Length("test")); - } - - [Fact] - public void Substring_Works() - { - Assert.Equal("es", StringBuiltins.Substring("test", 1, 2)); - } - - [Fact] - public void ToUpper_ToLower_Works() - { - Assert.Equal("TEST", StringBuiltins.ToUpper("test")); - Assert.Equal("test", StringBuiltins.ToLower("TEST")); - } - - [Fact] - public void Contains_Replace_Works() - { - Assert.True(StringBuiltins.Contains("abc", "b")); - Assert.Equal("axc", StringBuiltins.Replace("abc", "b", "x")); - } - - [Fact] - public void Trim_TrimStart_TrimEnd_Works() - { - Assert.Equal("abc", StringBuiltins.Trim(" abc ")); - Assert.Equal("abc ", StringBuiltins.TrimStart(" abc ")); - Assert.Equal(" abc", StringBuiltins.TrimEnd(" abc ")); - } - - [Fact] - public void IndexOf_LastIndexOf_Works() - { - Assert.Equal(1, StringBuiltins.IndexOf("abcab", "b")); - Assert.Equal(4, StringBuiltins.LastIndexOf("abcab", "b")); - } - - [Fact] - public void Split_Join_Works() - { - var arr = StringBuiltins.Split("a,b,c", ","); - Assert.Equal(new[] { "a", "b", "c" }, arr); - Assert.Equal("a-b-c", StringBuiltins.Join(arr, "-")); - } - - [Fact] - public void StartsWith_EndsWith_Works() - { - Assert.True(StringBuiltins.StartsWith("abc", "a")); - Assert.True(StringBuiltins.EndsWith("abc", "c")); - } - - [Fact] - public void PadLeft_PadRight_Works() - { - Assert.Equal(" ab", StringBuiltins.PadLeft("ab", 4)); - Assert.Equal("ab ", StringBuiltins.PadRight("ab", 4)); - } - } -} diff --git a/HypnoScript.Runtime.Tests/SystemBuiltinsTests.cs b/HypnoScript.Runtime.Tests/SystemBuiltinsTests.cs deleted file mode 100644 index 34d858d..0000000 --- a/HypnoScript.Runtime.Tests/SystemBuiltinsTests.cs +++ /dev/null @@ -1,55 +0,0 @@ -using Xunit; -using HypnoScript.Runtime.Builtins; - -namespace HypnoScript.Runtime.Tests -{ - public class SystemBuiltinsTests - { - [Fact] - public void GetEnvironmentVariable_Works() - { - var path = SystemBuiltins.GetEnvironmentVariable("PATH"); - Assert.False(string.IsNullOrEmpty(path)); - } - - [Fact] - public void GetCurrentDirectory_Works() - { - var dir = SystemBuiltins.GetCurrentDirectory(); - Assert.False(string.IsNullOrEmpty(dir)); - } - - [Fact] - public void GetMachineName_Works() - { - var name = SystemBuiltins.GetMachineName(); - Assert.False(string.IsNullOrEmpty(name)); - } - - [Fact] - public void GetUserName_Works() - { - var user = SystemBuiltins.GetUserName(); - Assert.False(string.IsNullOrEmpty(user)); - } - - [Fact] - public void GetOSVersion_Works() - { - var os = SystemBuiltins.GetOSVersion(); - Assert.False(string.IsNullOrEmpty(os)); - } - - [Fact] - public void GetProcessorCount_Works() - { - Assert.True(SystemBuiltins.GetProcessorCount() > 0); - } - - [Fact] - public void GetWorkingSet_Works() - { - Assert.True(SystemBuiltins.GetWorkingSet() > 0); - } - } -} diff --git a/HypnoScript.Runtime/Builtins/ArrayBuiltins.cs b/HypnoScript.Runtime/Builtins/ArrayBuiltins.cs deleted file mode 100644 index c39a1b3..0000000 --- a/HypnoScript.Runtime/Builtins/ArrayBuiltins.cs +++ /dev/null @@ -1,417 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace HypnoScript.Runtime.Builtins -{ - /// - /// Stellt Array-Funktionen für HypnoScript bereit. - /// - public static class ArrayBuiltins - { - /// - /// Reverses an array - /// - public static object[] ArrayReverse(object[] arr) - { - if (arr == null) return new object[0]; - var result = new object[arr.Length]; - Array.Copy(arr, result, arr.Length); - Array.Reverse(result); - return result; - } - - /// - /// Sorts an array - /// - public static object[] ArraySort(object[] arr) - { - if (arr == null) return new object[0]; - var result = new object[arr.Length]; - Array.Copy(arr, result, arr.Length); - Array.Sort(result); - return result; - } - - /// - /// Removes duplicates from an array - /// - public static object[] ArrayUnique(object[] arr) - { - if (arr == null) return new object[0]; - return arr.Distinct().ToArray(); - } - - /// - /// Filters an array using a predicate - /// - public static object[] ArrayFilter(object[] arr, Func predicate) - { - if (arr == null) return new object[0]; - return arr.Where(predicate).ToArray(); - } - - /// - /// Maps an array using a function - /// - public static object[] ArrayMap(object[] arr, Func mapper) - { - if (arr == null) return new object[0]; - return arr.Select(mapper).ToArray(); - } - - /// - /// Reduces an array using a function - /// - public static object ArrayReduce(object[] arr, Func reducer, object initial) - { - if (arr == null || arr.Length == 0) return initial; - return arr.Aggregate(initial, reducer); - } - - /// - /// Flattens a nested array - /// - public static object[] ArrayFlatten(object[] arr) - { - if (arr == null) return new object[0]; - - var result = new List(); - foreach (var item in arr) - { - if (item is object[] nestedArray) - { - result.AddRange(ArrayFlatten(nestedArray)); - } - else - { - result.Add(item); - } - } - return result.ToArray(); - } - - /// - /// Shuffles an array - /// - public static object[] ShuffleArray(object[] arr) - { - if (arr == null) return new object[0]; - var result = new object[arr.Length]; - Array.Copy(arr, result, arr.Length); - - var random = new Random(); - for (int i = result.Length - 1; i > 0; i--) - { - int j = random.Next(i + 1); - var temp = result[i]; - result[i] = result[j]; - result[j] = temp; - } - return result; - } - - /// - /// Calculates sum of numeric array elements - /// - public static double SumArray(object[] arr) - { - if (arr == null) return 0; - return arr.OfType().Sum(x => Convert.ToDouble(x)); - } - - /// - /// Calculates average of numeric array elements - /// - public static double AverageArray(object[] arr) - { - if (arr == null || arr.Length == 0) return 0; - return SumArray(arr) / arr.Length; - } - - /// - /// Creates an array with range of numbers - /// - public static object[] Range(int start, int count) - { - return Enumerable.Range(start, count).Cast().ToArray(); - } - - /// - /// Creates an array with repeated value - /// - public static object[] Repeat(object value, int count) - { - return Enumerable.Repeat(value, count).ToArray(); - } - - /// - /// Swaps two elements in an array - /// - public static void Swap(object[] arr, int i, int j) - { - if (arr == null || i < 0 || i >= arr.Length || j < 0 || j >= arr.Length) - return; - - var temp = arr[i]; - arr[i] = arr[j]; - arr[j] = temp; - } - - /// - /// Splits array into chunks - /// - public static object[][] ChunkArray(object[] arr, int chunkSize) - { - if (arr == null || chunkSize <= 0) return new object[0][]; - - var result = new List(); - for (int i = 0; i < arr.Length; i += chunkSize) - { - int length = Math.Min(chunkSize, arr.Length - i); - var chunk = new object[length]; - Array.Copy(arr, i, chunk, 0, length); - result.Add(chunk); - } - return result.ToArray(); - } - - /// - /// Calculates sum of array elements - /// - public static double ArraySum(object[] arr) => arr.OfType().Sum(x => Convert.ToDouble(x)); - - /// - /// Finds minimum value in array - /// - public static object? ArrayMin(object[] arr) => arr.Length == 0 ? null : arr.Min(); - - /// - /// Finds maximum value in array - /// - public static object? ArrayMax(object[] arr) => arr.Length == 0 ? null : arr.Max(); - - /// - /// Counts occurrences of a value in array - /// - public static int ArrayCount(object[] arr, object? value) => arr.Count(x => Equals(x, value)); - - /// - /// Removes a value from array - /// - public static object[] ArrayRemove(object[] arr, object? value) => arr.Where(x => !Equals(x, value)).ToArray(); - - /// - /// Removes duplicates from array - /// - public static object[] ArrayDistinct(object[] arr) => arr.Distinct().ToArray(); - - /// - /// Inserts an element at specific index - /// - public static object[] ArrayInsert(object[] arr, int index, object value) - { - if (arr == null) return new object[] { value }; - if (index < 0) index = 0; - if (index > arr.Length) index = arr.Length; - - var result = new object[arr.Length + 1]; - Array.Copy(arr, 0, result, 0, index); - result[index] = value; - Array.Copy(arr, index, result, index + 1, arr.Length - index); - return result; - } - - /// - /// Removes element at specific index - /// - public static object[] ArrayRemoveAt(object[] arr, int index) - { - if (arr == null || arr.Length == 0) return new object[0]; - if (index < 0 || index >= arr.Length) return arr; - - var result = new object[arr.Length - 1]; - Array.Copy(arr, 0, result, 0, index); - Array.Copy(arr, index + 1, result, index, arr.Length - index - 1); - return result; - } - - /// - /// Clears all elements from array - /// - public static void ArrayClear(object[] arr) => Array.Clear(arr, 0, arr.Length); - - /// - /// Creates a copy of array - /// - public static object[] ArrayCopy(object[] arr) - { - if (arr == null) return new object[0]; - var result = new object[arr.Length]; - Array.Copy(arr, result, arr.Length); - return result; - } - - /// - /// Resizes an array - /// - public static object[] ArrayResize(object[] arr, int newSize) - { - if (newSize < 0) return new object[0]; - var result = new object[newSize]; - if (arr != null) - { - Array.Copy(arr, result, Math.Min(arr.Length, newSize)); - } - return result; - } - - /// - /// Fills array with a value - /// - public static void ArrayFill(object[] arr, object value) => Array.Fill(arr, value); - - /// - /// Finds index of first occurrence - /// - public static int ArrayIndexOf(object[] arr, object value, int startIndex) => Array.IndexOf(arr, value, startIndex); - - /// - /// Finds index of last occurrence - /// - public static int ArrayLastIndexOf(object[] arr, object value) => Array.LastIndexOf(arr, value); - - /// - /// Gets subarray - /// - public static object[] ArraySubArray(object[] arr, int start, int end) - { - if (arr == null) return new object[0]; - if (start < 0) start = 0; - if (end > arr.Length) end = arr.Length; - if (start >= end) return new object[0]; - - var result = new object[end - start]; - Array.Copy(arr, start, result, 0, end - start); - return result; - } - - /// - /// Rotates array elements - /// - public static object[] ArrayRotate(object[] arr, int positions) - { - if (arr == null || arr.Length == 0) return new object[0]; - - positions = positions % arr.Length; - if (positions < 0) positions += arr.Length; - - var result = new object[arr.Length]; - Array.Copy(arr, positions, result, 0, arr.Length - positions); - Array.Copy(arr, 0, result, arr.Length - positions, positions); - return result; - } - - /// - /// Shuffles array with seed - /// - public static object[] ArrayShuffle(object[] arr, int seed) - { - if (arr == null) return new object[0]; - var result = ArrayCopy(arr); - var random = new Random(seed); - - for (int i = result.Length - 1; i > 0; i--) - { - int j = random.Next(i + 1); - Swap(result, i, j); - } - return result; - } - - /// - /// Partitions array based on predicate - /// - public static object[][] ArrayPartition(object[] arr, Func predicate) - { - if (arr == null) return new object[0][]; - - var trueItems = new List(); - var falseItems = new List(); - - foreach (var item in arr) - { - if (predicate(item)) - trueItems.Add(item); - else - falseItems.Add(item); - } - - return new object[][] { trueItems.ToArray(), falseItems.ToArray() }; - } - - /// - /// Gets length of array - /// - public static int ArrayLength(object[] arr) => arr?.Length ?? 0; - - /// - /// Gets element at index - /// - public static object? ArrayGet(object[] arr, int index) - { - if (arr == null || index < 0 || index >= arr.Length) return null; - return arr[index]; - } - - /// - /// Sets element at index - /// - public static void ArraySet(object[] arr, int index, object value) - { - if (arr != null && index >= 0 && index < arr.Length) - { - arr[index] = value; - } - } - - /// - /// Gets slice of array - /// - public static object[] ArraySlice(object[] arr, int start, int length) - { - if (arr == null || start < 0 || length <= 0) return new object[0]; - if (start >= arr.Length) return new object[0]; - - int actualLength = Math.Min(length, arr.Length - start); - var result = new object[actualLength]; - Array.Copy(arr, start, result, 0, actualLength); - return result; - } - - /// - /// Concatenates two arrays - /// - public static object[] ArrayConcat(object[] arr1, object[] arr2) - { - if (arr1 == null && arr2 == null) return new object[0]; - if (arr1 == null) return arr2 ?? new object[0]; - if (arr2 == null) return arr1; - - var result = new object[arr1.Length + arr2.Length]; - Array.Copy(arr1, 0, result, 0, arr1.Length); - Array.Copy(arr2, 0, result, arr1.Length, arr2.Length); - return result; - } - - /// - /// Finds index of element (without startIndex parameter) - /// - public static int ArrayIndexOf(object[] arr, object value) => Array.IndexOf(arr, value); - - /// - /// Checks if array contains element - /// - public static bool ArrayContains(object[] arr, object value) => arr?.Contains(value) ?? false; - } -} diff --git a/HypnoScript.Runtime/Builtins/DictionaryBuiltins.cs b/HypnoScript.Runtime/Builtins/DictionaryBuiltins.cs deleted file mode 100644 index 322fdf9..0000000 --- a/HypnoScript.Runtime/Builtins/DictionaryBuiltins.cs +++ /dev/null @@ -1,166 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace HypnoScript.Runtime.Builtins -{ - /// - /// Stellt Dictionary- und Record-Funktionen für HypnoScript bereit. - /// - public static class DictionaryBuiltins - { - /// - /// Creates a new dictionary - /// - public static Dictionary CreateDictionary() => new(); - - /// - /// Gets all keys from a dictionary - /// - public static string[] DictionaryKeys(Dictionary dict) => dict.Keys.ToArray(); - - /// - /// Gets all values from a dictionary - /// - public static object[] DictionaryValues(Dictionary dict) => dict.Values.ToArray(); - - /// - /// Checks if dictionary contains a key - /// - public static bool DictionaryContainsKey(Dictionary dict, string key) => dict.ContainsKey(key); - - /// - /// Gets a value from dictionary with optional default - /// - public static object? DictionaryGet(Dictionary dict, string key, object? defaultValue = null) => dict.TryGetValue(key, out var value) ? value : defaultValue; - - /// - /// Sets a value in dictionary - /// - public static void DictionarySet(Dictionary dict, string key, object value) => dict[key] = value; - - /// - /// Removes a key from dictionary - /// - public static bool DictionaryRemove(Dictionary dict, string key) => dict.Remove(key); - - /// - /// Gets count of dictionary entries - /// - public static int DictionaryCount(Dictionary dict) => dict.Count; - - /// - /// Creates a record from keys and values arrays - /// - public static Dictionary CreateRecord(string[] keys, object[] values) - { - var record = new Dictionary(); - for (int i = 0; i < Math.Min(keys.Length, values.Length); i++) - { - record[keys[i]] = values[i]; - } - return record; - } - - /// - /// Gets a value from a record - /// - public static object? GetRecordValue(Dictionary record, string key) - { - return record.TryGetValue(key, out var value) ? value : null; - } - - /// - /// Sets a value in a record - /// - public static void SetRecordValue(Dictionary record, string key, object value) - { - record[key] = value; - } - - /// - /// Merges two dictionaries - /// - public static Dictionary MergeDictionaries(Dictionary dict1, Dictionary dict2) - { - var result = new Dictionary(dict1); - foreach (var kvp in dict2) - { - result[kvp.Key] = kvp.Value; - } - return result; - } - - /// - /// Filters dictionary by predicate - /// - public static Dictionary FilterDictionary(Dictionary dict, Func predicate) - { - return dict.Where(kvp => predicate(kvp.Key, kvp.Value)) - .ToDictionary(kvp => kvp.Key, kvp => kvp.Value); - } - - /// - /// Maps dictionary values - /// - public static Dictionary MapDictionary(Dictionary dict, Func mapper) - { - return dict.ToDictionary(kvp => kvp.Key, kvp => mapper(kvp.Key, kvp.Value)); - } - - /// - /// Converts dictionary to array of key-value pairs - /// - public static object[] DictionaryToArray(Dictionary dict) - { - return dict.Select(kvp => new Dictionary { ["key"] = kvp.Key, ["value"] = kvp.Value }).Cast().ToArray(); - } - - /// - /// Creates dictionary from array of key-value pairs - /// - public static Dictionary ArrayToDictionary(object[] array) - { - var dict = new Dictionary(); - foreach (var item in array) - { - if (item is Dictionary kvp) - { - if (kvp.TryGetValue("key", out var key) && kvp.TryGetValue("value", out var value)) - { - dict[key.ToString()!] = value; - } - } - } - return dict; - } - - /// - /// Checks if dictionary is empty - /// - public static bool IsDictionaryEmpty(Dictionary dict) => dict.Count == 0; - - /// - /// Clears all entries from dictionary - /// - public static void ClearDictionary(Dictionary dict) => dict.Clear(); - - /// - /// Gets dictionary as sorted by keys - /// - public static Dictionary SortDictionaryByKeys(Dictionary dict) - { - return dict.OrderBy(kvp => kvp.Key) - .ToDictionary(kvp => kvp.Key, kvp => kvp.Value); - } - - /// - /// Gets dictionary as sorted by values - /// - public static Dictionary SortDictionaryByValues(Dictionary dict) - { - return dict.OrderBy(kvp => kvp.Value) - .ToDictionary(kvp => kvp.Key, kvp => kvp.Value); - } - } -} diff --git a/HypnoScript.Runtime/Builtins/DocGenerator.cs b/HypnoScript.Runtime/Builtins/DocGenerator.cs deleted file mode 100644 index 6496c25..0000000 --- a/HypnoScript.Runtime/Builtins/DocGenerator.cs +++ /dev/null @@ -1,97 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Text; -using System.Xml.Linq; - -namespace HypnoScript.Runtime.Builtins -{ - /// - /// Simple documentation generator for Builtins. Scans all Builtins/*.cs files and generates Markdown docs. - /// - public static class DocGenerator - { - private static XDocument? _xmlDocCache = null; - private static string? _xmlDocPathCache = null; - - public static void GenerateMarkdownDocs(string outputDir) - { - var builtinsDir = Path.GetDirectoryName(typeof(DocGenerator).Assembly.Location); - var builtinTypes = Assembly.GetExecutingAssembly().GetTypes() - .Where(t => t.IsClass && t.IsPublic && t.Namespace == "HypnoScript.Runtime.Builtins") - .ToList(); - foreach (var type in builtinTypes) - { - var sb = new StringBuilder(); - sb.AppendLine($"# {type.Name.Replace("Builtins", " Functions")}"); - sb.AppendLine(); - foreach (var method in type.GetMethods(BindingFlags.Public | BindingFlags.Static)) - { - sb.AppendLine($"## {method.Name}"); - sb.AppendLine(); - sb.AppendLine($"**Signature:** `{method}`"); - sb.AppendLine(); - // Try to get XML doc comment (if available) - var xmlComment = GetXmlDocComment(type, method); - if (!string.IsNullOrWhiteSpace(xmlComment)) - sb.AppendLine(xmlComment); - else - sb.AppendLine($"_No description available._"); - sb.AppendLine(); - } - var outFile = Path.Combine(outputDir, $"{type.Name.Replace("Builtins", "").ToLowerInvariant()}-functions.md"); - File.WriteAllText(outFile, sb.ToString()); - } - } - - private static string? GetXmlDocComment(Type type, System.Reflection.MethodInfo method) - { - // Ermittle den Pfad zur XML-Dokumentationsdatei (im gleichen Verzeichnis wie die DLL) - var asm = type.Assembly; - var asmLocation = asm.Location; - var xmlPath = Path.ChangeExtension(asmLocation, ".xml"); - if (!File.Exists(xmlPath)) - return null; - - // Cache das XML-Dokument für Performance - if (_xmlDocCache == null || _xmlDocPathCache != xmlPath) - { - _xmlDocCache = XDocument.Load(xmlPath); - _xmlDocPathCache = xmlPath; - } - var xml = _xmlDocCache; - if (xml == null) return null; - - // Erzeuge den Member-Name wie in der XML-Doku (z.B. M:Namespace.Type.Method(ParamType,ParamType)) - string memberName = "M:" + type.FullName + "." + method.Name; - var parameters = method.GetParameters(); - if (parameters.Length > 0) - { - memberName += "(" + string.Join(",", parameters.Select(p => GetXmlTypeName(p.ParameterType))) + ")"; - } - // Suche das passende member-Element - var member = xml.Descendants("member").FirstOrDefault(m => (string?)m.Attribute("name") == memberName); - if (member == null) - return null; - // Hole den -Text - var summary = member.Element("summary")?.Value?.Trim(); - return summary; - } - - // Hilfsfunktion: .NET-Typnamen zu XML-Doc-Typnamen - private static string GetXmlTypeName(Type t) - { - if (t.IsGenericType) - { - var genericType = t.GetGenericTypeDefinition(); - var genericArgs = t.GetGenericArguments(); - var baseName = genericType.FullName?.Split('`')[0]; - return baseName + "{" + string.Join(",", genericArgs.Select(GetXmlTypeName)) + "}"; - } - if (t.IsArray) - return GetXmlTypeName(t.GetElementType()!) + "[]"; - return t.FullName ?? t.Name; - } - } -} diff --git a/HypnoScript.Runtime/Builtins/FileBuiltins.cs b/HypnoScript.Runtime/Builtins/FileBuiltins.cs deleted file mode 100644 index 4d89d7b..0000000 --- a/HypnoScript.Runtime/Builtins/FileBuiltins.cs +++ /dev/null @@ -1,227 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using System.Collections.Generic; - -namespace HypnoScript.Runtime.Builtins -{ - /// - /// Stellt Datei- und Verzeichnisfunktionen für HypnoScript bereit. - /// - public static class FileBuiltins - { - /// Prüft, ob eine Datei existiert. - public static bool FileExists(string path) => File.Exists(path); - - /// Liest den gesamten Inhalt einer Datei als String. - public static string ReadFile(string path) - { - try { return File.ReadAllText(path); } - catch (Exception ex) { return $"[File Error] {ex.Message}"; } - } - - /// Schreibt einen String in eine Datei (überschreibt). - public static void WriteFile(string path, string content) - { - try { File.WriteAllText(path, content); } - catch (Exception ex) { HypnoBuiltins.Observe($"[File Error] {ex.Message}"); } - } - - /// Hängt einen String an eine Datei an. - public static void AppendFile(string path, string content) - { - try { File.AppendAllText(path, content); } - catch (Exception ex) { HypnoBuiltins.Observe($"[File Error] {ex.Message}"); } - } - - /// Liest alle Zeilen einer Datei als Array. - public static string[] ReadLines(string path) - { - try { return File.ReadAllLines(path); } - catch (Exception ex) { HypnoBuiltins.Observe($"[File Error] {ex.Message}"); return Array.Empty(); } - } - - /// Schreibt ein Array von Zeilen in eine Datei. - public static void WriteLines(string path, string[] lines) - { - try { File.WriteAllLines(path, lines); } - catch (Exception ex) { HypnoBuiltins.Observe($"[File Error] {ex.Message}"); } - } - - /// Gibt die Dateigröße in Bytes zurück. - public static long GetFileSize(string path) - { - try { return new FileInfo(path).Length; } - catch (Exception ex) { HypnoBuiltins.Observe($"[File Error] {ex.Message}"); return -1; } - } - - /// Gibt die Dateiendung zurück. - public static string GetFileExtension(string path) => Path.GetExtension(path); - - /// Gibt den Dateinamen zurück. - public static string GetFileName(string path) => Path.GetFileName(path); - - /// Gibt den Verzeichnisnamen zurück. - public static string GetDirectoryName(string path) => Path.GetDirectoryName(path) ?? string.Empty; - - /// Prüft, ob ein Verzeichnis existiert. - public static bool DirectoryExists(string path) => Directory.Exists(path); - - /// Erstellt ein Verzeichnis (rekursiv). - public static void CreateDirectory(string path) - { - try { Directory.CreateDirectory(path); } - catch (Exception ex) { HypnoBuiltins.Observe($"[Directory Error] {ex.Message}"); } - } - - /// Gibt alle Dateien im Verzeichnis zurück (optional mit Suchmuster). - public static string[] GetFiles(string path, string searchPattern = "*") - { - try { return Directory.GetFiles(path, searchPattern); } - catch (Exception ex) { HypnoBuiltins.Observe($"[Directory Error] {ex.Message}"); return Array.Empty(); } - } - - /// Gibt alle Unterverzeichnisse im Verzeichnis zurück. - public static string[] GetDirectories(string path) - { - try { return Directory.GetDirectories(path); } - catch (Exception ex) { HypnoBuiltins.Observe($"[Directory Error] {ex.Message}"); return Array.Empty(); } - } - - /// - /// Copies a file - /// - public static void FileCopy(string source, string dest) - { - try - { - File.Copy(source, dest, true); - } - catch (Exception ex) - { - throw new InvalidOperationException($"Failed to copy file: {ex.Message}"); - } - } - - /// - /// Moves a file - /// - public static void FileMove(string source, string dest) - { - try - { - File.Move(source, dest); - } - catch (Exception ex) - { - throw new InvalidOperationException($"Failed to move file: {ex.Message}"); - } - } - - /// - /// Deletes a file - /// - public static void FileDelete(string path) - { - try - { - if (File.Exists(path)) - { - File.Delete(path); - } - } - catch (Exception ex) - { - throw new InvalidOperationException($"Failed to delete file: {ex.Message}"); - } - } - - /// - /// Gets file information - /// - public static Dictionary GetFileInfo(string path) - { - try - { - var fileInfo = new FileInfo(path); - return new Dictionary - { - ["name"] = fileInfo.Name, - ["fullName"] = fileInfo.FullName, - ["size"] = fileInfo.Length, - ["creationTime"] = fileInfo.CreationTime.ToString("yyyy-MM-dd HH:mm:ss"), - ["lastWriteTime"] = fileInfo.LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss"), - ["extension"] = fileInfo.Extension, - ["exists"] = fileInfo.Exists - }; - } - catch - { - return new Dictionary - { - ["exists"] = false - }; - } - } - - /// - /// Checks if file is read-only - /// - public static bool IsFileReadOnly(string path) => (File.GetAttributes(path) & FileAttributes.ReadOnly) != 0; - - /// - /// Sets file read-only attribute - /// - public static void SetFileReadOnly(string path, bool readOnly) - { - try - { - var attributes = File.GetAttributes(path); - if (readOnly) - attributes |= FileAttributes.ReadOnly; - else - attributes &= ~FileAttributes.ReadOnly; - File.SetAttributes(path, attributes); - } - catch (Exception ex) - { - throw new InvalidOperationException($"Failed to set file attributes: {ex.Message}"); - } - } - - /// - /// Gets file creation time - /// - public static string GetFileCreationTime(string path) => File.GetCreationTime(path).ToString("yyyy-MM-dd HH:mm:ss"); - - /// - /// Gets file last write time - /// - public static string GetFileLastWriteTime(string path) => File.GetLastWriteTime(path).ToString("yyyy-MM-dd HH:mm:ss"); - - /// - /// Gets file size in MB - /// - public static double GetFileSizeMB(string path) => new FileInfo(path).Length / (1024.0 * 1024.0); - - /// - /// Gets file name without extension - /// - public static string GetFileNameWithoutExtension(string path) => Path.GetFileNameWithoutExtension(path); - - /// - /// Combines path components - /// - public static string CombinePath(string path1, string path2) => Path.Combine(path1, path2); - - /// - /// Gets current directory - /// - public static string GetCurrentDirectory() => Environment.CurrentDirectory; - - /// - /// Gets temporary path - /// - public static string GetTempPath() => Path.GetTempPath(); - } -} diff --git a/HypnoScript.Runtime/Builtins/HashingBuiltins.cs b/HypnoScript.Runtime/Builtins/HashingBuiltins.cs deleted file mode 100644 index fa53c5b..0000000 --- a/HypnoScript.Runtime/Builtins/HashingBuiltins.cs +++ /dev/null @@ -1,165 +0,0 @@ -using System; -using System.Security.Cryptography; -using System.Text; - -namespace HypnoScript.Runtime.Builtins -{ - /// - /// Stellt Hashing- und Encoding-Funktionen für HypnoScript bereit. - /// - public static class HashingBuiltins - { - /// - /// Creates MD5 hash of input string - /// - public static string HashMD5(string input) - { - if (string.IsNullOrEmpty(input)) return ""; - - using var md5 = MD5.Create(); - var inputBytes = Encoding.UTF8.GetBytes(input); - var hashBytes = md5.ComputeHash(inputBytes); - - return Convert.ToHexString(hashBytes).ToLower(); - } - - /// - /// Creates SHA256 hash of input string - /// - public static string HashSHA256(string input) - { - if (string.IsNullOrEmpty(input)) return ""; - - using var sha256 = SHA256.Create(); - var inputBytes = Encoding.UTF8.GetBytes(input); - var hashBytes = sha256.ComputeHash(inputBytes); - - return Convert.ToHexString(hashBytes).ToLower(); - } - - /// - /// Creates SHA512 hash of input string - /// - public static string HashSHA512(string input) - { - if (string.IsNullOrEmpty(input)) return ""; - - using var sha512 = SHA512.Create(); - var inputBytes = Encoding.UTF8.GetBytes(input); - var hashBytes = sha512.ComputeHash(inputBytes); - - return Convert.ToHexString(hashBytes).ToLower(); - } - - /// - /// Base64 encodes a string - /// - public static string Base64Encode(string input) - { - if (string.IsNullOrEmpty(input)) return ""; - var bytes = Encoding.UTF8.GetBytes(input); - return Convert.ToBase64String(bytes); - } - - /// - /// Base64 decodes a string - /// - public static string Base64Decode(string input) - { - if (string.IsNullOrEmpty(input)) return ""; - - try - { - var bytes = Convert.FromBase64String(input); - return Encoding.UTF8.GetString(bytes); - } - catch - { - return ""; - } - } - - /// - /// URL encodes a string - /// - public static string UrlEncode(string input) - { - if (string.IsNullOrEmpty(input)) return ""; - return Uri.EscapeDataString(input); - } - - /// - /// URL decodes a string - /// - public static string UrlDecode(string input) - { - if (string.IsNullOrEmpty(input)) return ""; - - try - { - return Uri.UnescapeDataString(input); - } - catch - { - return input; - } - } - - /// - /// HTML encodes a string - /// - public static string HtmlEncode(string input) - { - if (string.IsNullOrEmpty(input)) return ""; - return System.Web.HttpUtility.HtmlEncode(input); - } - - /// - /// HTML decodes a string - /// - public static string HtmlDecode(string input) - { - if (string.IsNullOrEmpty(input)) return ""; - return System.Web.HttpUtility.HtmlDecode(input); - } - - /// - /// Creates a simple hash from input - /// - public static int SimpleHash(string input) - { - if (string.IsNullOrEmpty(input)) return 0; - - int hash = 0; - foreach (char c in input) - { - hash = ((hash << 5) - hash) + c; - hash = hash & hash; // Convert to 32-bit integer - } - return hash; - } - - /// - /// Creates a checksum from input - /// - public static string CreateChecksum(string input) - { - if (string.IsNullOrEmpty(input)) return ""; - - using var sha1 = SHA1.Create(); - var inputBytes = Encoding.UTF8.GetBytes(input); - var hashBytes = sha1.ComputeHash(inputBytes); - - return Convert.ToHexString(hashBytes).ToLower(); - } - - /// - /// Verifies a checksum - /// - public static bool VerifyChecksum(string input, string expectedChecksum) - { - var actualChecksum = CreateChecksum(input); - return string.Equals(actualChecksum, expectedChecksum, StringComparison.OrdinalIgnoreCase); - } - } -} diff --git a/HypnoScript.Runtime/Builtins/HypnoticBuiltins.cs b/HypnoScript.Runtime/Builtins/HypnoticBuiltins.cs deleted file mode 100644 index fbbd63e..0000000 --- a/HypnoScript.Runtime/Builtins/HypnoticBuiltins.cs +++ /dev/null @@ -1,229 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace HypnoScript.Runtime.Builtins -{ - /// - /// Stellt hypnotische und trancebezogene Funktionen für HypnoScript bereit. - /// - public static class HypnoticBuiltins - { - /// - /// Enters a deep trance state for the specified duration. - /// - /// Duration in milliseconds (default: 5000) - public static void DeepTrance(int duration = 5000) - { - HypnoBuiltins.Observe("Entering deep trance..."); - HypnoBuiltins.Drift(duration); - HypnoBuiltins.Observe("Emerging from trance..."); - } - - /// - /// Performs a hypnotic countdown from the specified number. - /// - /// Starting number for countdown (default: 10) - public static void HypnoticCountdown(int from = 10) - { - for (int i = from; i > 0; i--) - { - HypnoBuiltins.Observe($"You are feeling very sleepy... {i}"); - HypnoBuiltins.Drift(1000); - } - HypnoBuiltins.Observe("You are now in a deep hypnotic state."); - } - - /// - /// Performs a trance induction for the specified subject. - /// - /// Name of the subject (default: "Subject") - public static void TranceInduction(string subjectName = "Subject") - { - HypnoBuiltins.Observe($"Welcome {subjectName}, you are about to enter a deep trance..."); - HypnoBuiltins.Drift(2000); - HypnoBuiltins.Observe("Take a deep breath and relax..."); - HypnoBuiltins.Drift(1500); - HypnoBuiltins.Observe("With each breath, you feel more and more relaxed..."); - HypnoBuiltins.Drift(1500); - HypnoBuiltins.Observe("Your mind is becoming clear and focused..."); - HypnoBuiltins.Drift(1000); - } - - /// - /// Guides the subject through hypnotic visualization. - /// - /// Scene to visualize (default: "a peaceful garden") - public static void HypnoticVisualization(string scene = "a peaceful garden") - { - HypnoBuiltins.Observe($"Imagine yourself in {scene}..."); - HypnoBuiltins.Drift(2000); - HypnoBuiltins.Observe("Feel the tranquility surrounding you..."); - HypnoBuiltins.Drift(1500); - HypnoBuiltins.Observe("Every detail becomes clearer and more vivid..."); - HypnoBuiltins.Drift(1500); - } - - /// - /// Performs progressive relaxation with the specified number of steps. - /// - /// Number of relaxation steps (default: 5) - public static void ProgressiveRelaxation(int steps = 5) - { - HypnoBuiltins.Observe("Let's begin progressive relaxation..."); - for (int i = 1; i <= steps; i++) - { - HypnoBuiltins.Observe($"Step {i}: Relax your muscles deeper and deeper..."); - HypnoBuiltins.Drift(1500); - } - HypnoBuiltins.Observe("You are now completely relaxed and at peace."); - } - - /// - /// Gives a hypnotic suggestion to the subject. - /// - /// The suggestion to implant - public static void HypnoticSuggestion(string suggestion) - { - HypnoBuiltins.Observe("I will now give you a powerful suggestion..."); - HypnoBuiltins.Drift(1000); - HypnoBuiltins.Observe($"Remember this: {suggestion}"); - HypnoBuiltins.Drift(2000); - HypnoBuiltins.Observe("This suggestion will become stronger with each passing moment."); - } - - /// - /// Deepens the trance state by the specified number of levels. - /// - /// Number of deepening levels (default: 3) - public static void TranceDeepening(int levels = 3) - { - HypnoBuiltins.Observe("We will now go deeper into trance..."); - for (int i = 1; i <= levels; i++) - { - HypnoBuiltins.Observe($"Level {i}: Going deeper..."); - HypnoBuiltins.Drift(2000); - } - HypnoBuiltins.Observe("You are now in the deepest level of trance."); - } - - /// - /// Guides the subject through hypnotic breathing exercises. - /// - /// Number of breathing cycles (default: 5) - public static void HypnoticBreathing(int cycles = 5) - { - HypnoBuiltins.Observe("Let's practice hypnotic breathing..."); - for (int i = 1; i <= cycles; i++) - { - HypnoBuiltins.Observe($"Cycle {i}: Breathe in deeply..."); - HypnoBuiltins.Drift(2000); - HypnoBuiltins.Observe("Hold your breath..."); - HypnoBuiltins.Drift(1000); - HypnoBuiltins.Observe("Now exhale slowly..."); - HypnoBuiltins.Drift(2000); - } - HypnoBuiltins.Observe("You are now in a state of perfect calm."); - } - - /// - /// Creates a hypnotic anchor for the specified state. - /// - /// The anchor state to create (default: "peaceful") - public static void HypnoticAnchoring(string anchor = "peaceful") - { - HypnoBuiltins.Observe($"I will now create a powerful anchor for '{anchor}'..."); - HypnoBuiltins.Drift(1500); - HypnoBuiltins.Observe("Every time you think of this anchor, you will feel this way..."); - HypnoBuiltins.Drift(2000); - HypnoBuiltins.Observe($"Your '{anchor}' anchor is now established."); - } - - /// - /// Performs hypnotic age regression to the specified age. - /// - /// Target age for regression (default: 10) - public static void HypnoticRegression(int age = 10) - { - HypnoBuiltins.Observe($"We will now travel back in time to when you were {age} years old..."); - HypnoBuiltins.Drift(3000); - HypnoBuiltins.Observe("You can see yourself as a child..."); - HypnoBuiltins.Drift(2000); - HypnoBuiltins.Observe("Feel the memories and emotions of that time..."); - HypnoBuiltins.Drift(2000); - HypnoBuiltins.Observe("You are now experiencing your past self."); - } - - /// - /// Performs hypnotic future progression to the specified number of years ahead. - /// - /// Number of years into the future (default: 5) - public static void HypnoticFutureProgression(int years = 5) - { - HypnoBuiltins.Observe($"Let's travel forward {years} years into your future..."); - HypnoBuiltins.Drift(3000); - HypnoBuiltins.Observe("You can see your future self..."); - HypnoBuiltins.Drift(2000); - HypnoBuiltins.Observe("Feel the wisdom and experience of your future..."); - HypnoBuiltins.Drift(2000); - HypnoBuiltins.Observe("You are now connected to your future potential."); - } - - /// - /// Establishes a pattern matching system for the specified pattern. - /// - /// The pattern to establish - public static void HypnoticPatternMatching(string pattern) - { - HypnoBuiltins.Observe($"I will now establish a pattern matching system for '{pattern}'..."); - HypnoBuiltins.Drift(2000); - HypnoBuiltins.Observe("Your mind will automatically recognize this pattern..."); - HypnoBuiltins.Drift(1500); - HypnoBuiltins.Observe("Every time you encounter this pattern, you will respond automatically..."); - HypnoBuiltins.Drift(2000); - HypnoBuiltins.Observe($"The '{pattern}' pattern is now deeply embedded in your subconscious."); - } - - /// - /// Alters the subject's perception of time by the specified factor. - /// - /// Time dilation factor (default: 2.0) - public static void HypnoticTimeDilation(double factor = 2.0) - { - HypnoBuiltins.Observe($"I will now alter your perception of time by a factor of {factor}..."); - HypnoBuiltins.Drift(3000); - HypnoBuiltins.Observe("Time will feel different to you now..."); - HypnoBuiltins.Drift(2000); - HypnoBuiltins.Observe("Minutes will feel like hours, or hours like minutes..."); - HypnoBuiltins.Drift(2000); - HypnoBuiltins.Observe("Your time perception has been successfully modified."); - } - - /// - /// Enhances the subject's memory capabilities. - /// - public static void HypnoticMemoryEnhancement() - { - HypnoBuiltins.Observe("I will now enhance your memory capabilities..."); - HypnoBuiltins.Drift(2000); - HypnoBuiltins.Observe("Your ability to remember and recall information will improve..."); - HypnoBuiltins.Drift(2000); - HypnoBuiltins.Observe("You will find it easier to learn and retain new knowledge..."); - HypnoBuiltins.Drift(2000); - HypnoBuiltins.Observe("Your memory enhancement is now active."); - } - - /// - /// Boosts the subject's creative potential. - /// - public static void HypnoticCreativityBoost() - { - HypnoBuiltins.Observe("I will now unlock your creative potential..."); - HypnoBuiltins.Drift(2000); - HypnoBuiltins.Observe("Your imagination will become more vivid and active..."); - HypnoBuiltins.Drift(2000); - HypnoBuiltins.Observe("Creative solutions will come to you more easily..."); - HypnoBuiltins.Drift(2000); - HypnoBuiltins.Observe("Your creativity is now enhanced."); - } - } -} diff --git a/HypnoScript.Runtime/Builtins/MathBuiltins.cs b/HypnoScript.Runtime/Builtins/MathBuiltins.cs deleted file mode 100644 index 1b23311..0000000 --- a/HypnoScript.Runtime/Builtins/MathBuiltins.cs +++ /dev/null @@ -1,275 +0,0 @@ -using System; -using System.Linq; -using System.Numerics; - -namespace HypnoScript.Runtime.Builtins -{ - /// - /// Mathematische Builtins für HypnoScript (ausgelagert aus HypnoBuiltins) - /// - public static class MathBuiltins - { - /// Gibt den Absolutwert einer Zahl zurück. - public static double Abs(double x) => Math.Abs(x); - /// Sinus (im Gradmaß, nicht Radiant). - public static double Sin(double x) => Math.Sin(x * Math.PI / 180.0); // Grad zu Radiant - /// Kosinus (im Gradmaß, nicht Radiant). - public static double Cos(double x) => Math.Cos(x * Math.PI / 180.0); - /// Tangens (im Gradmaß, nicht Radiant). - public static double Tan(double x) => Math.Tan(x * Math.PI / 180.0); - /// Quadratwurzel. - public static double Sqrt(double x) => Math.Sqrt(x); - /// Potenzfunktion (x^y). - public static double Pow(double x, double y) => Math.Pow(x, y); - /// Rundet ab. - public static double Floor(double x) => Math.Floor(x); - /// Rundet auf. - public static double Ceiling(double x) => Math.Ceiling(x); - /// Rundet auf die nächste Ganzzahl. - public static double Round(double x) => Math.Round(x); - /// Natürlicher Logarithmus. - public static double Log(double x) => Math.Log(x); - /// Zehner-Logarithmus. - public static double Log10(double x) => Math.Log10(x); - /// Exponentialfunktion (e^x). - public static double Exp(double x) => Math.Exp(x); - /// Maximum zweier Zahlen. - public static double Max(double x, double y) => Math.Max(x, y); - /// Minimum zweier Zahlen. - public static double Min(double x, double y) => Math.Min(x, y); - /// Zufallszahl zwischen 0 und 1 (nicht kryptografisch). - public static double Random() => HypnoBuiltins._random.NextDouble(); - /// Zufallszahl im Bereich [min, max] (nicht kryptografisch). - public static int RandomInt(int min, int max) => HypnoBuiltins._random.Next(min, max + 1); - - /// - /// Calculates the factorial of a number - /// - public static double Factorial(int n) - { - if (n < 0) throw new ArgumentException("Factorial is not defined for negative numbers"); - if (n == 0 || n == 1) return 1; - - double result = 1; - for (int i = 2; i <= n; i++) - { - result *= i; - } - return result; - } - - /// - /// Calculates the greatest common divisor of two numbers - /// - public static double GCD(double a, double b) - { - a = Math.Abs(a); - b = Math.Abs(b); - - while (b != 0) - { - double temp = b; - b = a % b; - a = temp; - } - return a; - } - - /// - /// Calculates the least common multiple of two numbers - /// - public static double LCM(double a, double b) - { - return Math.Abs(a * b) / GCD(a, b); - } - - /// - /// Converts degrees to radians - /// - public static double DegreesToRadians(double degrees) => degrees * Math.PI / 180.0; - - /// - /// Converts radians to degrees - /// - public static double RadiansToDegrees(double radians) => radians * 180.0 / Math.PI; - - /// - /// Arc sine in degrees - /// - public static double Asin(double x) => Math.Asin(x) * 180.0 / Math.PI; - - /// - /// Arc cosine in degrees - /// - public static double Acos(double x) => Math.Acos(x) * 180.0 / Math.PI; - - /// - /// Arc tangent in degrees - /// - public static double Atan(double x) => Math.Atan(x) * 180.0 / Math.PI; - - /// - /// Arc tangent of y/x in degrees - /// - public static double Atan2(double y, double x) => Math.Atan2(y, x) * 180.0 / Math.PI; - - /// - /// Clamps a value between min and max - /// - public static double Clamp(double value, double min, double max) => Math.Max(min, Math.Min(max, value)); - - /// - /// Returns the sign of a number (-1, 0, or 1) - /// - public static int Sign(double value) => Math.Sign(value); - - /// - /// Checks if a number is even - /// - public static bool IsEven(int value) => value % 2 == 0; - - /// - /// Checks if a number is odd - /// - public static bool IsOdd(int value) => value % 2 != 0; - - /// - /// Checks if a number is prime - /// - public static bool IsPrime(int n) - { - if (n < 2) return false; - if (n == 2) return true; - if (n % 2 == 0) return false; - - for (int i = 3; i <= Math.Sqrt(n); i += 2) - { - if (n % i == 0) return false; - } - return true; - } - - /// - /// Calculates factorial for large numbers using BigInteger - /// - public static BigInteger FactorialBig(int n) - { - if (n < 0) throw new ArgumentException("Factorial is not defined for negative numbers"); - if (n == 0 || n == 1) return 1; - - BigInteger result = 1; - for (int i = 2; i <= n; i++) - { - result *= i; - } - return result; - } - - /// - /// Converts a number to hexadecimal string - /// - public static string ToHex(long n) => n.ToString("X"); - - /// - /// Converts a number to binary string - /// - public static string ToBinary(long n) => Convert.ToString(n, 2); - - /// - /// Rounds a number to specified decimal places - /// - public static double RoundToDecimal(double x, int decimals) => Math.Round(x, decimals); - - /// - /// Ceilings a number to specified decimal places - /// - public static double CeilingToDecimal(double x, int decimals) => Math.Ceiling(x * Math.Pow(10, decimals)) / Math.Pow(10, decimals); - - /// - /// Floors a number to specified decimal places - /// - public static double FloorToDecimal(double x, int decimals) => Math.Floor(x * Math.Pow(10, decimals)) / Math.Pow(10, decimals); - - /// - /// Calculates modulo operation - /// - public static double Modulo(double a, double b) => a % b; - - /// - /// Checks if a number is a power of 2 - /// - public static bool PowerOf2(int n) => n > 0 && (n & (n - 1)) == 0; - - /// - /// Finds the next power of 2 greater than or equal to n - /// - public static int NextPowerOf2(int n) - { - if (n <= 0) return 1; - n--; - n |= n >> 1; - n |= n >> 2; - n |= n >> 4; - n |= n >> 8; - n |= n >> 16; - return n + 1; - } - - /// - /// Checks if a number is a perfect square - /// - public static bool IsPerfectSquare(int n) - { - if (n < 0) return false; - int root = (int)Math.Sqrt(n); - return root * root == n; - } - - /// - /// Integer square root - /// - public static int SqrtInt(int n) => (int)Math.Sqrt(n); - - /// - /// Calculates GCD of an array of numbers - /// - public static int GCDArray(object[] arr) - { - if (arr.Length == 0) return 0; - if (arr.Length == 1) return Convert.ToInt32(arr[0]); - - int result = Convert.ToInt32(arr[0]); - for (int i = 1; i < arr.Length; i++) - { - result = (int)GCD(result, Convert.ToDouble(arr[i])); - } - return result; - } - - /// - /// Calculates LCM of an array of numbers - /// - public static int LCMArray(object[] arr) - { - if (arr.Length == 0) return 0; - if (arr.Length == 1) return Convert.ToInt32(arr[0]); - - int result = Convert.ToInt32(arr[0]); - for (int i = 1; i < arr.Length; i++) - { - result = (int)LCM(result, Convert.ToDouble(arr[i])); - } - return result; - } - - /// - /// Calculates sum of digits in a number - /// - public static int SumOfDigits(long n) => n.ToString().Sum(c => c - '0'); - - /// - /// Reverses the digits of a number - /// - public static long ReverseNumber(long n) => long.Parse(new string(n.ToString().Reverse().ToArray())); - } -} diff --git a/HypnoScript.Runtime/Builtins/NetworkBuiltins.cs b/HypnoScript.Runtime/Builtins/NetworkBuiltins.cs deleted file mode 100644 index 0861936..0000000 --- a/HypnoScript.Runtime/Builtins/NetworkBuiltins.cs +++ /dev/null @@ -1,118 +0,0 @@ -using System; -using System.Net.Http; -using System.Threading.Tasks; -using System.Threading; -using System.Web; -using System.Text.Json; - -namespace HypnoScript.Runtime.Builtins -{ - /// - /// Stellt Netzwerk- und HTTP-Funktionen für HypnoScript bereit. - /// - public static class NetworkBuiltins - { - private static readonly HttpClient _httpClient = new HttpClient(); - - /// - /// Makes an HTTP GET request - /// - public static async Task HttpGet(string url) - { - try - { - var response = await _httpClient.GetAsync(url); - response.EnsureSuccessStatusCode(); - return await response.Content.ReadAsStringAsync(); - } - catch (Exception ex) - { - throw new InvalidOperationException($"HTTP GET failed: {ex.Message}"); - } - } - - /// - /// Makes an HTTP POST request - /// - public static async Task HttpPost(string url, string content) - { - try - { - var httpContent = new StringContent(content); - var response = await _httpClient.PostAsync(url, httpContent); - response.EnsureSuccessStatusCode(); - return await response.Content.ReadAsStringAsync(); - } - catch (Exception ex) - { - throw new InvalidOperationException($"HTTP POST failed: {ex.Message}"); - } - } - - /// - /// Makes an HTTP POST request with JSON content - /// - public static async Task HttpPostJson(string url, object data) - { - try - { - var json = JsonSerializer.Serialize(data); - var httpContent = new StringContent(json, System.Text.Encoding.UTF8, "application/json"); - var response = await _httpClient.PostAsync(url, httpContent); - response.EnsureSuccessStatusCode(); - return await response.Content.ReadAsStringAsync(); - } - catch (Exception ex) - { - throw new InvalidOperationException($"HTTP POST JSON failed: {ex.Message}"); - } - } - /// Prüft, ob eine URL gültig ist. - public static bool IsValidUrl(string url) => Uri.TryCreate(url, UriKind.Absolute, out _); - /// Prüft, ob eine IP-Adresse gültig ist. - public static bool IsValidIPAddress(string str) => System.Net.IPAddress.TryParse(str, out _); - /// Prüft, ob ein Port gültig ist (1-65535). - public static bool IsValidPort(int port) => port >= 1 && port <= 65535; - /// URL-Encoding. - public static string UrlEncode(string str) => HttpUtility.UrlEncode(str); - /// URL-Decoding. - public static string UrlDecode(string str) => HttpUtility.UrlDecode(str); - /// HTML-Encoding. - public static string HtmlEncode(string str) => HttpUtility.HtmlEncode(str); - /// HTML-Decoding. - public static string HtmlDecode(string str) => HttpUtility.HtmlDecode(str); - /// Extrahiert die Domain aus einer URL. - public static string ExtractDomain(string url) - { - try { var uri = new Uri(url); return uri.Host; } catch { return string.Empty; } - } - /// Extrahiert den Pfad aus einer URL. - public static string ExtractPath(string url) - { - try { var uri = new Uri(url); return uri.AbsolutePath; } catch { return string.Empty; } - } - /// Prüft, ob eine URL auf localhost zeigt. - public static bool IsLocalhost(string url) - { - try { var uri = new Uri(url); return uri.Host == "localhost" || uri.Host == "127.0.0.1"; } catch { return false; } - } - - /// - /// Validates email format - /// - public static bool IsValidEmail(string email) - { - if (string.IsNullOrEmpty(email)) return false; - - try - { - var regex = new System.Text.RegularExpressions.Regex(@"^[^@\s]+@[^@\s]+\.[^@\s]+$"); - return regex.IsMatch(email); - } - catch - { - return false; - } - } - } -} diff --git a/HypnoScript.Runtime/Builtins/PerformanceBuiltins.cs b/HypnoScript.Runtime/Builtins/PerformanceBuiltins.cs deleted file mode 100644 index f4c58bc..0000000 --- a/HypnoScript.Runtime/Builtins/PerformanceBuiltins.cs +++ /dev/null @@ -1,182 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Threading; - -namespace HypnoScript.Runtime.Builtins -{ - /// - /// Stellt Performance- und Benchmark-Funktionen für HypnoScript bereit. - /// - public static class PerformanceBuiltins - { - /// - /// Gets performance metrics - /// - public static Dictionary GetPerformanceMetrics() - { - var process = Process.GetCurrentProcess(); - return new Dictionary - { - ["memoryUsage"] = GC.GetTotalMemory(false), - ["workingSet"] = process.WorkingSet64, - ["cpuTime"] = process.TotalProcessorTime.TotalSeconds, - ["threadCount"] = process.Threads.Count, - ["handleCount"] = process.HandleCount, - ["startTime"] = process.StartTime.ToString("yyyy-MM-dd HH:mm:ss") - }; - } - - /// - /// Benchmarks a function - /// - public static double Benchmark(Func func, int iterations) - { - var stopwatch = Stopwatch.StartNew(); - for (int i = 0; i < iterations; i++) - { - func(); - } - stopwatch.Stop(); - return stopwatch.ElapsedMilliseconds / (double)iterations; - } - - /// - /// Gets memory usage in MB - /// - public static long GetMemoryUsage() => GC.GetTotalMemory(false); - - /// - /// Gets CPU usage (approximate) - /// - public static double GetCPUUsage() - { - // Simple CPU usage approximation - return Environment.ProcessorCount * 100.0; - } - - /// - /// Forces garbage collection - /// - public static void ForceGarbageCollection() - { - GC.Collect(); - GC.WaitForPendingFinalizers(); - GC.Collect(); - } - - /// - /// Gets process information - /// - public static Dictionary GetProcessInfo() - { - var process = Process.GetCurrentProcess(); - return new Dictionary - { - ["id"] = process.Id, - ["name"] = process.ProcessName, - ["memory"] = process.WorkingSet64, - ["cpuTime"] = process.TotalProcessorTime.TotalSeconds, - ["startTime"] = process.StartTime.ToString("yyyy-MM-dd HH:mm:ss") - }; - } - - /// - /// Gets system information - /// - public static Dictionary GetSystemInfo() - { - return new Dictionary - { - ["os"] = Environment.OSVersion.ToString(), - ["machineName"] = Environment.MachineName, - ["processorCount"] = Environment.ProcessorCount, - ["workingSet"] = Environment.WorkingSet, - ["userName"] = Environment.UserName, - ["currentDirectory"] = Environment.CurrentDirectory - }; - } - - /// - /// Measures execution time of a function - /// - public static double MeasureExecutionTime(Func func) - { - var stopwatch = Stopwatch.StartNew(); - func(); - stopwatch.Stop(); - return stopwatch.ElapsedMilliseconds; - } - - /// - /// Measures execution time of an action - /// - public static double MeasureExecutionTime(Action action) - { - var stopwatch = Stopwatch.StartNew(); - action(); - stopwatch.Stop(); - return stopwatch.ElapsedMilliseconds; - } - - /// - /// Gets current tick count - /// - public static long GetTickCount() => Environment.TickCount64; - - /// - /// Sleeps for specified milliseconds - /// - public static void Sleep(int ms) => Thread.Sleep(ms); - - /// - /// Debug print memory information - /// - public static void DebugPrintMemory() - { - var memory = GC.GetTotalMemory(false); - Console.WriteLine($"[DEBUG] Memory Usage: {memory / 1024 / 1024} MB"); - } - - /// - /// Debug print stack trace - /// - public static void DebugPrintStackTrace() - { - Console.WriteLine($"[DEBUG] Stack Trace: {Environment.StackTrace}"); - } - - /// - /// Debug print environment information - /// - public static void DebugPrintEnvironment() - { - Console.WriteLine($"[DEBUG] OS: {Environment.OSVersion}"); - Console.WriteLine($"[DEBUG] Machine: {Environment.MachineName}"); - Console.WriteLine($"[DEBUG] Processors: {Environment.ProcessorCount}"); - Console.WriteLine($"[DEBUG] Memory: {Environment.WorkingSet / 1024 / 1024} MB"); - } - - /// - /// Gets call stack - /// - public static string[] GetCallStack() - { - return Environment.StackTrace.Split('\n', StringSplitOptions.RemoveEmptyEntries); - } - - /// - /// Gets exception information - /// - public static Dictionary GetExceptionInfo(Exception ex) - { - return new Dictionary - { - ["message"] = ex.Message, - ["type"] = ex.GetType().Name, - ["stackTrace"] = ex.StackTrace ?? "", - ["source"] = ex.Source ?? "" - }; - } - } -} diff --git a/HypnoScript.Runtime/Builtins/StatisticsBuiltins.cs b/HypnoScript.Runtime/Builtins/StatisticsBuiltins.cs deleted file mode 100644 index c4e6cda..0000000 --- a/HypnoScript.Runtime/Builtins/StatisticsBuiltins.cs +++ /dev/null @@ -1,229 +0,0 @@ -using System; -using System.Linq; - -namespace HypnoScript.Runtime.Builtins -{ - /// - /// Stellt Statistik- und Analysefunktionen für HypnoScript bereit. - /// - public static class StatisticsBuiltins - { - /// - /// Calculates linear regression - /// - public static double LinearRegression(object[] x, object[] y) - { - if (x.Length != y.Length || x.Length < 2) return 0; - - var xValues = x.Select(v => Convert.ToDouble(v)).ToArray(); - var yValues = y.Select(v => Convert.ToDouble(v)).ToArray(); - - double sumX = xValues.Sum(); - double sumY = yValues.Sum(); - double sumXY = xValues.Zip(yValues, (a, b) => a * b).Sum(); - double sumX2 = xValues.Select(v => v * v).Sum(); - - int n = xValues.Length; - double slope = (n * sumXY - sumX * sumY) / (n * sumX2 - sumX * sumX); - - return slope; - } - - /// - /// Calculates mean of values - /// - public static double CalculateMean(object[] values) - { - if (values.Length == 0) return 0; - var nums = values.Select(v => Convert.ToDouble(v)).ToArray(); - return nums.Sum() / nums.Length; - } - - /// - /// Calculates standard deviation - /// - public static double CalculateStandardDeviation(object[] values) - { - if (values.Length < 2) return 0; - - var nums = values.Select(v => Convert.ToDouble(v)).ToArray(); - double mean = nums.Sum() / nums.Length; - double sumSquaredDiff = nums.Sum(v => Math.Pow(v - mean, 2)); - - return Math.Sqrt(sumSquaredDiff / (nums.Length - 1)); - } - - /// - /// Calculates variance - /// - public static double CalculateVariance(object[] values) - { - if (values.Length < 2) return 0; - - var nums = values.Select(v => Convert.ToDouble(v)).ToArray(); - double mean = nums.Sum() / nums.Length; - double sumSquaredDiff = nums.Sum(v => Math.Pow(v - mean, 2)); - - return sumSquaredDiff / (nums.Length - 1); - } - - /// - /// Calculates median - /// - public static double CalculateMedian(object[] values) - { - if (values.Length == 0) return 0; - - var nums = values.Select(v => Convert.ToDouble(v)).OrderBy(v => v).ToArray(); - int n = nums.Length; - - if (n % 2 == 0) - { - return (nums[n / 2 - 1] + nums[n / 2]) / 2; - } - else - { - return nums[n / 2]; - } - } - - /// - /// Calculates mode - /// - public static double CalculateMode(object[] values) - { - if (values.Length == 0) return 0; - - var groups = values.GroupBy(v => Convert.ToDouble(v)) - .OrderByDescending(g => g.Count()) - .ThenBy(g => g.Key); - - return groups.First().Key; - } - - /// - /// Calculates range - /// - public static double CalculateRange(object[] values) - { - if (values.Length == 0) return 0; - - var nums = values.Select(v => Convert.ToDouble(v)).ToArray(); - return nums.Max() - nums.Min(); - } - - /// - /// Calculates sum of array elements - /// - public static double ArraySum(object[] arr) => arr.OfType().Sum(x => Convert.ToDouble(x)); - - /// - /// Calculates average of array elements - /// - public static double AverageArray(object[] arr) - { - if (arr == null || arr.Length == 0) return 0; - return SumArray(arr) / arr.Length; - } - - /// - /// Calculates sum of numeric array elements - /// - public static double SumArray(object[] arr) - { - if (arr == null) return 0; - return arr.OfType().Sum(x => Convert.ToDouble(x)); - } - - /// - /// Finds minimum value in array - /// - public static object? ArrayMin(object[] arr) => arr.Length == 0 ? null : arr.Min(); - - /// - /// Finds maximum value in array - /// - public static object? ArrayMax(object[] arr) => arr.Length == 0 ? null : arr.Max(); - - /// - /// Counts occurrences of a value in array - /// - public static int ArrayCount(object[] arr, object? value) => arr.Count(x => Equals(x, value)); - - /// - /// Calculates correlation coefficient - /// - public static double CalculateCorrelation(object[] x, object[] y) - { - if (x.Length != y.Length || x.Length < 2) return 0; - - var xValues = x.Select(v => Convert.ToDouble(v)).ToArray(); - var yValues = y.Select(v => Convert.ToDouble(v)).ToArray(); - - double meanX = xValues.Sum() / xValues.Length; - double meanY = yValues.Sum() / yValues.Length; - - double numerator = xValues.Zip(yValues, (a, b) => (a - meanX) * (b - meanY)).Sum(); - double denominatorX = xValues.Sum(v => Math.Pow(v - meanX, 2)); - double denominatorY = yValues.Sum(v => Math.Pow(v - meanY, 2)); - - if (denominatorX == 0 || denominatorY == 0) return 0; - - return numerator / Math.Sqrt(denominatorX * denominatorY); - } - - /// - /// Calculates percentile - /// - public static double CalculatePercentile(object[] values, double percentile) - { - if (values.Length == 0) return 0; - if (percentile < 0 || percentile > 100) return 0; - - var nums = values.Select(v => Convert.ToDouble(v)).OrderBy(v => v).ToArray(); - double index = (percentile / 100.0) * (nums.Length - 1); - - if (index == Math.Floor(index)) - { - return nums[(int)index]; - } - else - { - int lower = (int)Math.Floor(index); - int upper = (int)Math.Ceiling(index); - double weight = index - lower; - return nums[lower] * (1 - weight) + nums[upper] * weight; - } - } - - /// - /// Calculates interquartile range - /// - public static double CalculateIQR(object[] values) - { - double q1 = CalculatePercentile(values, 25); - double q3 = CalculatePercentile(values, 75); - return q3 - q1; - } - - /// - /// Detects outliers using IQR method - /// - public static object[] DetectOutliers(object[] values) - { - if (values.Length < 4) return new object[0]; - - double q1 = CalculatePercentile(values, 25); - double q3 = CalculatePercentile(values, 75); - double iqr = q3 - q1; - double lowerBound = q1 - 1.5 * iqr; - double upperBound = q3 + 1.5 * iqr; - - return values.Where(v => - { - double val = Convert.ToDouble(v); - return val < lowerBound || val > upperBound; - }).ToArray(); - } - } -} diff --git a/HypnoScript.Runtime/Builtins/StringBuiltins.cs b/HypnoScript.Runtime/Builtins/StringBuiltins.cs deleted file mode 100644 index 8b06764..0000000 --- a/HypnoScript.Runtime/Builtins/StringBuiltins.cs +++ /dev/null @@ -1,373 +0,0 @@ -using System; -using System.Linq; -using System.Text.RegularExpressions; - -namespace HypnoScript.Runtime.Builtins -{ - /// - /// String manipulation built-in functions for HypnoScript - /// - public static class StringBuiltins - { - /// Länge eines Strings. - public static int Length(string str) => str.Length; - /// Substring ab Start mit Länge. - public static string Substring(string str, int start, int length) => str.Substring(start, length); - /// Wandelt in Großbuchstaben um. - public static string ToUpper(string str) => str.ToUpper(); - /// Wandelt in Kleinbuchstaben um. - public static string ToLower(string str) => str.ToLower(); - /// Prüft, ob ein String einen Teilstring enthält. - public static bool Contains(string str, string substring) => str.Contains(substring); - /// Ersetzt alle Vorkommen eines Teilstrings. - public static string Replace(string str, string oldValue, string newValue) => str.Replace(oldValue, newValue); - /// Trimmt Leerzeichen am Anfang und Ende. - public static string Trim(string str) => str.Trim(); - /// Trimmt Leerzeichen am Anfang. - public static string TrimStart(string str) => str.TrimStart(); - /// Trimmt Leerzeichen am Ende. - public static string TrimEnd(string str) => str.TrimEnd(); - /// Index des ersten Vorkommens eines Teilstrings. - public static int IndexOf(string str, string substring) => str.IndexOf(substring); - /// Index des letzten Vorkommens eines Teilstrings. - public static int LastIndexOf(string str, string substring) => str.LastIndexOf(substring); - /// Teilt einen String anhand eines Separators. - public static string[] Split(string str, string separator) => str.Split(separator); - /// Fügt ein String-Array mit Separator zusammen. - public static string Join(string[] array, string separator) => string.Join(separator, array); - /// Prüft, ob ein String mit Präfix beginnt. - public static bool StartsWith(string str, string prefix) => str.StartsWith(prefix); - /// Prüft, ob ein String mit Suffix endet. - public static bool EndsWith(string str, string suffix) => str.EndsWith(suffix); - /// Links-Auffüllen auf Breite mit Zeichen. - public static string PadLeft(string str, int width, char paddingChar = ' ') => str.PadLeft(width, paddingChar); - /// Rechts-Auffüllen auf Breite mit Zeichen. - public static string PadRight(string str, int width, char paddingChar = ' ') => str.PadRight(width, paddingChar); - /// Fügt einen Wert an einer bestimmten Position in einen String ein. - public static string Insert(string str, int index, string value) - { - if (str == null || value == null) return str ?? string.Empty; - if (index < 0 || index > str.Length) return str; - return str.Insert(index, value); - } - /// Entfernt eine bestimmte Anzahl von Zeichen ab einer Position. - public static string Remove(string str, int start, int count) - { - if (str == null) return string.Empty; - if (start < 0 || count < 0 || start + count > str.Length) return str; - return str.Remove(start, count); - } - /// Vergleicht zwei Strings lexikografisch. - public static int Compare(string str1, string str2) - { - if (str1 == null && str2 == null) return 0; - if (str1 == null) return -1; - if (str2 == null) return 1; - return string.Compare(str1, str2, StringComparison.Ordinal); - } - /// Vergleicht zwei Strings ohne Beachtung der Groß-/Kleinschreibung. - public static bool EqualsIgnoreCase(string str1, string str2) - { - if (str1 == null || str2 == null) return false; - return string.Equals(str1, str2, StringComparison.OrdinalIgnoreCase); - } - /// Prüft, ob ein String ein Palindrom ist. - public static bool IsPalindrome(string str) - { - if (string.IsNullOrEmpty(str)) return false; - int len = str.Length; - for (int i = 0; i < len / 2; i++) - if (str[i] != str[len - i - 1]) return false; - return true; - } - /// Zählt die Wörter in einem String. - public static int CountWords(string str) - { - if (string.IsNullOrWhiteSpace(str)) return 0; - return str.Split(new[] { ' ', '\t', '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries).Length; - } - /// Extrahiert alle Ziffern aus einem String. - public static string ExtractNumbers(string str) - { - if (str == null) return string.Empty; - return new string(str.Where(char.IsDigit).ToArray()); - } - /// Extrahiert alle Buchstaben aus einem String. - public static string ExtractLetters(string str) - { - if (str == null) return string.Empty; - return new string(str.Where(char.IsLetter).ToArray()); - } - /// - /// Reverses a string - /// - public static string Reverse(string str) - { - if (string.IsNullOrEmpty(str)) return str; - return new string(str.Reverse().ToArray()); - } - /// - /// Capitalizes the first letter of a string - /// - public static string Capitalize(string str) - { - if (string.IsNullOrEmpty(str)) return str; - return char.ToUpper(str[0]) + str.Substring(1).ToLower(); - } - /// - /// Converts string to title case - /// - public static string TitleCase(string str) - { - if (string.IsNullOrEmpty(str)) return str; - - var words = str.Split(' '); - for (int i = 0; i < words.Length; i++) - { - if (!string.IsNullOrEmpty(words[i])) - { - words[i] = Capitalize(words[i]); - } - } - return string.Join(" ", words); - } - /// - /// Counts occurrences of a substring in a string - /// - public static int CountOccurrences(string str, string substring) - { - if (string.IsNullOrEmpty(str) || string.IsNullOrEmpty(substring)) - return 0; - - int count = 0; - int index = 0; - while ((index = str.IndexOf(substring, index)) != -1) - { - count++; - index += substring.Length; - } - return count; - } - /// - /// Removes all whitespace from a string - /// - public static string RemoveWhitespace(string str) - { - if (string.IsNullOrEmpty(str)) return str; - return new string(str.Where(c => !char.IsWhiteSpace(c)).ToArray()); - } - /// - /// Checks if a string is null or empty - /// - public static bool IsNullOrEmpty(string? str) => string.IsNullOrEmpty(str); - /// - /// Repeats a string n times - /// - public static string RepeatString(string str, int n) => string.Concat(Enumerable.Repeat(str, n)); - /// - /// Reverses the order of words in a string - /// - public static string ReverseWords(string str) => string.Join(" ", str.Split(' ').Reverse()); - /// - /// Truncates a string to specified length - /// - public static string Truncate(string str, int length) => str.Length <= length ? str : str.Substring(0, length); - /// - /// Removes all digits from a string - /// - public static string RemoveDigits(string str) => new string(str.Where(c => !char.IsDigit(c)).ToArray()); - /// - /// Splits a string by length - /// - public static string[] StringSplitByLength(string str, int maxLength) - { - if (string.IsNullOrEmpty(str) || maxLength <= 0) return new string[0]; - - var result = new List(); - for (int i = 0; i < str.Length; i += maxLength) - { - int length = Math.Min(maxLength, str.Length - i); - result.Add(str.Substring(i, length)); - } - return result.ToArray(); - } - /// - /// Rotates characters in a string - /// - public static string StringRotate(string str, int positions) - { - if (string.IsNullOrEmpty(str)) return str; - - positions = positions % str.Length; - if (positions < 0) positions += str.Length; - - return str.Substring(positions) + str.Substring(0, positions); - } - /// - /// Shuffles characters in a string - /// - public static string StringShuffle(string str) - { - if (string.IsNullOrEmpty(str)) return str; - - var chars = str.ToCharArray(); - var random = new Random(); - - for (int i = chars.Length - 1; i > 0; i--) - { - int j = random.Next(i + 1); - char temp = chars[i]; - chars[i] = chars[j]; - chars[j] = temp; - } - - return new string(chars); - } - /// - /// Validates email format - /// - public static bool IsValidEmail(string email) - { - if (string.IsNullOrEmpty(email)) return false; - - try - { - var regex = new Regex(@"^[^@\s]+@[^@\s]+\.[^@\s]+$"); - return regex.IsMatch(email); - } - catch - { - return false; - } - } - /// - /// Validates URL format - /// - public static bool IsValidUrl(string url) - { - return Uri.TryCreate(url, UriKind.Absolute, out _); - } - /// - /// Validates JSON format - /// - public static bool IsValidJson(string json) - { - if (string.IsNullOrEmpty(json)) return false; - - try - { - using var doc = System.Text.Json.JsonDocument.Parse(json); - return true; - } - catch - { - return false; - } - } - /// - /// Formats a number with specified decimal places - /// - public static string FormatNumber(double number, int decimals = 2) - { - return number.ToString($"F{decimals}"); - } - /// - /// Formats a number as currency - /// - public static string FormatCurrency(double amount, string currency = "USD") - { - return $"{currency} {amount:F2}"; - } - /// - /// Formats a number as percentage - /// - public static string FormatPercentage(double value) - { - return $"{value:F2}%"; - } - /// - /// Validates phone number format - /// - public static bool IsValidPhoneNumber(string str) - { - if (string.IsNullOrEmpty(str)) return false; - var regex = new Regex(@"^[\+]?[1-9][\d]{0,15}$"); - return regex.IsMatch(str.Replace(" ", "").Replace("-", "").Replace("(", "").Replace(")", "")); - } - /// - /// Validates credit card format - /// - public static bool IsValidCreditCard(string str) - { - if (string.IsNullOrEmpty(str)) return false; - var regex = new Regex(@"^[\d\s\-]{13,19}$"); - return regex.IsMatch(str); - } - /// - /// Validates postal code format - /// - public static bool IsValidPostalCode(string str) - { - if (string.IsNullOrEmpty(str)) return false; - var regex = new Regex(@"^[\d\w\s\-]{3,10}$"); - return regex.IsMatch(str); - } - /// - /// Validates SSN format - /// - public static bool IsValidSSN(string str) - { - if (string.IsNullOrEmpty(str)) return false; - var regex = new Regex(@"^\d{3}-?\d{2}-?\d{4}$"); - return regex.IsMatch(str); - } - /// - /// Formats phone number - /// - public static string FormatPhoneNumber(string str) - { - if (string.IsNullOrEmpty(str)) return str; - var digits = ExtractNumbers(str); - if (digits.Length == 10) - return $"({digits.Substring(0, 3)}) {digits.Substring(3, 3)}-{digits.Substring(6)}"; - return str; - } - /// - /// Formats credit card number - /// - public static string FormatCreditCard(string str) - { - if (string.IsNullOrEmpty(str)) return str; - var digits = ExtractNumbers(str); - if (digits.Length >= 13 && digits.Length <= 19) - { - var groups = new List(); - for (int i = 0; i < digits.Length; i += 4) - { - groups.Add(digits.Substring(i, Math.Min(4, digits.Length - i))); - } - return string.Join(" ", groups); - } - return str; - } - /// - /// Masks part of a string - /// - public static string MaskString(string str, char maskChar, int start, int end) - { - if (string.IsNullOrEmpty(str) || start < 0 || end > str.Length || start >= end) - return str; - - return str.Substring(0, start) + new string(maskChar, end - start) + str.Substring(end); - } - /// - /// Generates a random string - /// - public static string GenerateRandomString(int length) - { - const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; - var random = new Random(); - return new string(Enumerable.Repeat(chars, length).Select(s => s[random.Next(s.Length)]).ToArray()); - } - } -} diff --git a/HypnoScript.Runtime/Builtins/SystemBuiltins.cs b/HypnoScript.Runtime/Builtins/SystemBuiltins.cs deleted file mode 100644 index 73581f3..0000000 --- a/HypnoScript.Runtime/Builtins/SystemBuiltins.cs +++ /dev/null @@ -1,235 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; - -namespace HypnoScript.Runtime.Builtins -{ - /// - /// Stellt System- und Umgebungsfunktionen für HypnoScript bereit. - /// - public static class SystemBuiltins - { - /// - /// Clears the console screen - /// - public static void ClearScreen() - { - Console.Clear(); - } - - /// - /// Plays a system beep - /// - public static void Beep(int frequency = 800, int duration = 200) - { -#if WINDOWS - Console.Beep(frequency, duration); -#else - // Fallback für nicht-Windows Plattformen - System.Threading.Thread.Sleep(duration); -#endif - } - - /// - /// Gets environment variable - /// - public static string GetEnvironmentVariable(string name) - { - return Environment.GetEnvironmentVariable(name) ?? ""; - } - - /// - /// Exits the application - /// - public static void Exit(int code = 0) - { - Environment.Exit(code); - } - - /// - /// Gets machine name - /// - public static string GetMachineName() => Environment.MachineName; - - /// - /// Gets user name - /// - public static string GetUserName() => Environment.UserName; - - /// - /// Gets OS version - /// - public static string GetOSVersion() => Environment.OSVersion.ToString(); - - /// - /// Gets processor count - /// - public static int GetProcessorCount() => Environment.ProcessorCount; - - /// - /// Gets working set memory - /// - public static long GetWorkingSet() => Environment.WorkingSet; - - /// - /// Gets memory usage - /// - public static long GetMemoryUsage() => GC.GetTotalMemory(false); - - /// - /// Gets CPU usage (approximate) - /// - public static double GetCPUUsage() - { - // Simple CPU usage approximation - return Environment.ProcessorCount * 100.0; - } - - /// - /// Gets process information - /// - public static Dictionary GetProcessInfo() - { - var process = Process.GetCurrentProcess(); - return new Dictionary - { - ["id"] = process.Id, - ["name"] = process.ProcessName, - ["memory"] = process.WorkingSet64, - ["cpuTime"] = process.TotalProcessorTime.TotalSeconds, - ["startTime"] = process.StartTime.ToString("yyyy-MM-dd HH:mm:ss") - }; - } - - /// - /// Gets system information - /// - public static Dictionary GetSystemInfo() - { - return new Dictionary - { - ["os"] = Environment.OSVersion.ToString(), - ["machineName"] = Environment.MachineName, - ["processorCount"] = Environment.ProcessorCount, - ["workingSet"] = Environment.WorkingSet, - ["userName"] = Environment.UserName, - ["currentDirectory"] = Environment.CurrentDirectory - }; - } - - /// - /// Gets all environment variables - /// - public static Dictionary GetEnvVars() => Environment.GetEnvironmentVariables().Cast().ToDictionary(e => (string)e.Key, e => e.Value as string ?? ""); - - /// - /// Gets tick count - /// - public static long GetTickCount() => Environment.TickCount64; - - /// - /// Sleeps for specified milliseconds - /// - public static void Sleep(int ms) => System.Threading.Thread.Sleep(ms); - - /// - /// Plays a sound - /// - public static void PlaySound(int frequency = 800, int duration = 200) - { -#if WINDOWS - Console.Beep(frequency, duration); -#else - System.Threading.Thread.Sleep(duration); -#endif - } - - /// - /// Simulates vibration (platform dependent) - /// - public static void Vibrate(int duration = 1000) - { - // Platform-specific vibration would go here - // For now, just sleep - System.Threading.Thread.Sleep(duration); - } - - /// - /// Debug print memory information - /// - public static void DebugPrintMemory() - { - var memory = GC.GetTotalMemory(false); - Console.WriteLine($"[DEBUG] Memory Usage: {memory / 1024 / 1024} MB"); - } - - /// - /// Debug print stack trace - /// - public static void DebugPrintStackTrace() - { - Console.WriteLine($"[DEBUG] Stack Trace: {Environment.StackTrace}"); - } - - /// - /// Debug print environment information - /// - public static void DebugPrintEnvironment() - { - Console.WriteLine($"[DEBUG] OS: {Environment.OSVersion}"); - Console.WriteLine($"[DEBUG] Machine: {Environment.MachineName}"); - Console.WriteLine($"[DEBUG] Processors: {Environment.ProcessorCount}"); - Console.WriteLine($"[DEBUG] Memory: {Environment.WorkingSet / 1024 / 1024} MB"); - } - - /// - /// Benchmarks a function - /// - public static double Benchmark(Func func, int iterations) - { - var stopwatch = Stopwatch.StartNew(); - for (int i = 0; i < iterations; i++) - { - func(); - } - stopwatch.Stop(); - return stopwatch.ElapsedMilliseconds / (double)iterations; - } - - /// - /// Gets call stack - /// - public static string[] GetCallStack() - { - return Environment.StackTrace.Split('\n', StringSplitOptions.RemoveEmptyEntries); - } - - /// - /// Gets exception information - /// - public static Dictionary GetExceptionInfo(Exception ex) - { - return new Dictionary - { - ["message"] = ex.Message, - ["type"] = ex.GetType().Name, - ["stackTrace"] = ex.StackTrace ?? "", - ["source"] = ex.Source ?? "" - }; - } - - /// - /// Logs a message - /// - public static void Log(string message, string level = "INFO") - { - Console.WriteLine($"[{level}] {message}"); - } - - /// - /// Traces a message - /// - public static void Trace(string message) => Log(message, "TRACE"); - } -} diff --git a/HypnoScript.Runtime/Builtins/TimeBuiltins.cs b/HypnoScript.Runtime/Builtins/TimeBuiltins.cs deleted file mode 100644 index 39c7639..0000000 --- a/HypnoScript.Runtime/Builtins/TimeBuiltins.cs +++ /dev/null @@ -1,186 +0,0 @@ -using System; -using System.Globalization; - -namespace HypnoScript.Runtime.Builtins -{ - /// - /// Stellt Zeit- und Datumsfunktionen für HypnoScript bereit. - /// - public static class TimeBuiltins - { - /// - /// Gets current Unix timestamp - /// - public static int GetCurrentTime() => (int)DateTimeOffset.UtcNow.ToUnixTimeSeconds(); - - /// - /// Gets current date as string - /// - public static string GetCurrentDate() => DateTime.Now.ToString("yyyy-MM-dd"); - - /// - /// Gets current time as string - /// - public static string GetCurrentTimeString() => DateTime.Now.ToString("HH:mm:ss"); - - /// - /// Gets current date and time as string - /// - public static string GetCurrentDateTime() => DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); - - /// - /// Formats date time with custom format - /// - public static string FormatDateTime(string format = "yyyy-MM-dd HH:mm:ss") - { - return DateTime.Now.ToString(format); - } - - /// - /// Gets day of week (0=Sunday, 6=Saturday) - /// - public static int GetDayOfWeek() => (int)DateTime.Now.DayOfWeek; - - /// - /// Gets day of year - /// - public static int GetDayOfYear() => DateTime.Now.DayOfYear; - - /// - /// Checks if year is leap year - /// - public static bool IsLeapYear(int year) => DateTime.IsLeapYear(year); - - /// - /// Gets number of days in month - /// - public static int GetDaysInMonth(int year, int month) => DateTime.DaysInMonth(year, month); - - /// - /// Gets timezone information - /// - public static string GetTimeZone() => TimeZoneInfo.Local.DisplayName; - - /// - /// Converts time between timezones - /// - public static string ConvertTimeZone(string date, string fromZone, string toZone) - { - try - { - var fromTz = TimeZoneInfo.FindSystemTimeZoneById(fromZone); - var toTz = TimeZoneInfo.FindSystemTimeZoneById(toZone); - var dt = DateTime.Parse(date); - var utc = TimeZoneInfo.ConvertTimeToUtc(dt, fromTz); - var converted = TimeZoneInfo.ConvertTimeFromUtc(utc, toTz); - return converted.ToString("yyyy-MM-dd HH:mm:ss"); - } - catch - { - return date; - } - } - - /// - /// Gets week of year - /// - public static int GetWeekOfYear(string date) - { - var dt = DateTime.Parse(date); - var calendar = CultureInfo.InvariantCulture.Calendar; - return calendar.GetWeekOfYear(dt, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday); - } - - /// - /// Gets quarter of year - /// - public static int GetQuarter(string date) - { - var dt = DateTime.Parse(date); - return (dt.Month - 1) / 3 + 1; - } - - /// - /// Checks if date is weekend - /// - public static bool IsWeekend(string date) - { - var dt = DateTime.Parse(date); - return dt.DayOfWeek == DayOfWeek.Saturday || dt.DayOfWeek == DayOfWeek.Sunday; - } - - /// - /// Checks if date is business day - /// - public static bool IsBusinessDay(string date) => !IsWeekend(date); - - /// - /// Adds business days to date - /// - public static string AddBusinessDays(string date, int days) - { - var dt = DateTime.Parse(date); - var added = 0; - while (added < days) - { - dt = dt.AddDays(1); - if (IsBusinessDay(dt.ToString("yyyy-MM-dd"))) - { - added++; - } - } - return dt.ToString("yyyy-MM-dd"); - } - - /// - /// Gets days between two dates - /// - public static int GetDaysBetween(string date1, string date2) - { - var dt1 = DateTime.Parse(date1); - var dt2 = DateTime.Parse(date2); - return (int)(dt2 - dt1).TotalDays; - } - - /// - /// Calculates age from birth date - /// - public static int GetAge(string birthDate) - { - var birth = DateTime.Parse(birthDate); - var today = DateTime.Today; - var age = today.Year - birth.Year; - if (birth.Date > today.AddYears(-age)) age--; - return age; - } - - /// - /// Checks if date is leap day - /// - public static bool IsLeapDay(string date) - { - var dt = DateTime.Parse(date); - return dt.Month == 2 && dt.Day == 29; - } - - /// - /// Adds days to date - /// - public static string AddDays(string date, int n) => DateTime.Parse(date).AddDays(n).ToString("yyyy-MM-dd"); - - /// - /// Adds months to date - /// - public static string AddMonths(string date, int n) => DateTime.Parse(date).AddMonths(n).ToString("yyyy-MM-dd"); - - /// - /// Adds years to date - /// - public static string AddYears(string date, int n) => DateTime.Parse(date).AddYears(n).ToString("yyyy-MM-dd"); - - /// - /// Parses date string - /// - public static string ParseDate(string str) => DateTime.Parse(str).ToString("yyyy-MM-dd"); - } -} diff --git a/HypnoScript.Runtime/Builtins/UtilityBuiltins.cs b/HypnoScript.Runtime/Builtins/UtilityBuiltins.cs deleted file mode 100644 index 2dc9588..0000000 --- a/HypnoScript.Runtime/Builtins/UtilityBuiltins.cs +++ /dev/null @@ -1,432 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Security.Cryptography; -using System.Text.Json; - -namespace HypnoScript.Runtime.Builtins -{ - /// - /// Stellt Hilfsfunktionen und Konvertierungen für HypnoScript bereit. - /// - public static class UtilityBuiltins - { - /// - /// Converts a value to an integer. - /// - /// The value to convert - /// The converted integer value - public static int ToInt(object? value) => Convert.ToInt32(value); - - /// - /// Converts a value to a double. - /// - /// The value to convert - /// The converted double value - public static double ToDouble(object? value) => Convert.ToDouble(value); - - /// - /// Converts a value to a string. - /// - /// The value to convert - /// The converted string value - public static string ToString(object? value) => value?.ToString() ?? ""; - - /// - /// Converts a value to a boolean. - /// - /// The value to convert - /// The converted boolean value - public static bool ToBoolean(object? value) => Convert.ToBoolean(value); - - /// - /// Converts a value to a character. - /// - /// The value to convert - /// The converted character value - public static char ToChar(object? value) => Convert.ToChar(value); - - /// - /// Serializes an object to JSON format. - /// - /// The object to serialize - /// JSON string representation - public static string ToJson(object? obj) - { - try - { - return JsonSerializer.Serialize(obj, new JsonSerializerOptions { WriteIndented = true }); - } - catch (Exception ex) - { - HypnoBuiltins.Observe($"Error serializing to JSON: {ex.Message}"); - return "{}"; - } - } - - /// - /// Deserializes a JSON string to an object. - /// - /// The JSON string to deserialize - /// The deserialized object - public static object? FromJson(string json) - { - try - { - return JsonSerializer.Deserialize(json); - } - catch (Exception ex) - { - HypnoBuiltins.Observe($"Error deserializing JSON: {ex.Message}"); - return null; - } - } - - /// - /// Calculates the factorial of a number. - /// - /// The number to calculate factorial for - /// The factorial result - public static double Factorial(int n) - { - if (n < 0) return double.NaN; - if (n <= 1) return 1; - double result = 1; - for (int i = 2; i <= n; i++) - result *= i; - return result; - } - - /// - /// Calculates the greatest common divisor of two numbers. - /// - /// First number - /// Second number - /// The GCD - public static double GCD(double a, double b) - { - a = Math.Abs(a); - b = Math.Abs(b); - while (b != 0) - { - var temp = b; - b = a % b; - a = temp; - } - return a; - } - - /// - /// Calculates the least common multiple of two numbers. - /// - /// First number - /// Second number - /// The LCM - public static double LCM(double a, double b) - { - return Math.Abs(a * b) / GCD(a, b); - } - - /// - /// Converts degrees to radians. - /// - /// Angle in degrees - /// Angle in radians - public static double DegreesToRadians(double degrees) => degrees * Math.PI / 180.0; - - /// - /// Converts radians to degrees. - /// - /// Angle in radians - /// Angle in degrees - public static double RadiansToDegrees(double radians) => radians * 180.0 / Math.PI; - - /// - /// Calculates arcsine in degrees. - /// - /// The value - /// Arcsine in degrees - public static double Asin(double x) => Math.Asin(x) * 180.0 / Math.PI; - - /// - /// Calculates arccosine in degrees. - /// - /// The value - /// Arccosine in degrees - public static double Acos(double x) => Math.Acos(x) * 180.0 / Math.PI; - - /// - /// Calculates arctangent in degrees. - /// - /// The value - /// Arctangent in degrees - public static double Atan(double x) => Math.Atan(x) * 180.0 / Math.PI; - - /// - /// Calculates arctangent of y/x in degrees. - /// - /// Y coordinate - /// X coordinate - /// Arctangent in degrees - public static double Atan2(double y, double x) => Math.Atan2(y, x) * 180.0 / Math.PI; - - /// - /// Reverses a string. - /// - /// The string to reverse - /// The reversed string - public static string Reverse(string str) - { - var chars = str.ToCharArray(); - Array.Reverse(chars); - return new string(chars); - } - - /// - /// Capitalizes the first letter of a string. - /// - /// The string to capitalize - /// The capitalized string - public static string Capitalize(string str) - { - if (string.IsNullOrEmpty(str)) return str; - return char.ToUpper(str[0]) + str.Substring(1).ToLower(); - } - - /// - /// Converts a string to title case. - /// - /// The string to convert - /// The title case string - public static string TitleCase(string str) - { - if (string.IsNullOrEmpty(str)) return str; - var words = str.Split(' '); - for (int i = 0; i < words.Length; i++) - { - if (!string.IsNullOrEmpty(words[i])) - words[i] = Capitalize(words[i]); - } - return string.Join(" ", words); - } - - /// - /// Counts occurrences of a substring in a string. - /// - /// The main string - /// The substring to count - /// Number of occurrences - public static int CountOccurrences(string str, string substring) - { - if (string.IsNullOrEmpty(str) || string.IsNullOrEmpty(substring)) - return 0; - - int count = 0; - int index = 0; - while ((index = str.IndexOf(substring, index)) != -1) - { - count++; - index += substring.Length; - } - return count; - } - - /// - /// Removes all whitespace from a string. - /// - /// The string to process - /// String without whitespace - public static string RemoveWhitespace(string str) - { - return string.Join("", str.Where(c => !char.IsWhiteSpace(c))); - } - - /// - /// Reverses an array. - /// - /// The array to reverse - /// The reversed array - public static object[] ArrayReverse(object[] arr) - { - var result = new object[arr.Length]; - Array.Copy(arr, result, arr.Length); - Array.Reverse(result); - return result; - } - - /// - /// Sorts an array. - /// - /// The array to sort - /// The sorted array - public static object[] ArraySort(object[] arr) - { - var result = new object[arr.Length]; - Array.Copy(arr, result, arr.Length); - Array.Sort(result); - return result; - } - - /// - /// Removes duplicate elements from an array. - /// - /// The array to process - /// Array with unique elements - public static object[] ArrayUnique(object[] arr) - { - return arr.Distinct().ToArray(); - } - - /// - /// Filters an array using a predicate function. - /// - /// The array to filter - /// The filter function - /// The filtered array - public static object[] ArrayFilter(object[] arr, Func predicate) - { - return arr.Where(predicate).ToArray(); - } - - /// - /// Creates an MD5 hash of a string. - /// - /// The string to hash - /// The MD5 hash - public static string HashMD5(string input) - { - using (var md5 = MD5.Create()) - { - var hash = md5.ComputeHash(Encoding.UTF8.GetBytes(input)); - return Convert.ToHexString(hash).ToLower(); - } - } - - /// - /// Creates a SHA256 hash of a string. - /// - /// The string to hash - /// The SHA256 hash - public static string HashSHA256(string input) - { - using (var sha256 = SHA256.Create()) - { - var hash = sha256.ComputeHash(Encoding.UTF8.GetBytes(input)); - return Convert.ToHexString(hash).ToLower(); - } - } - - /// - /// Encodes a string to Base64. - /// - /// The string to encode - /// The Base64 encoded string - public static string Base64Encode(string input) - { - var bytes = Encoding.UTF8.GetBytes(input); - return Convert.ToBase64String(bytes); - } - - /// - /// Decodes a Base64 string. - /// - /// The Base64 string to decode - /// The decoded string - public static string Base64Decode(string input) - { - try - { - var bytes = Convert.FromBase64String(input); - return Encoding.UTF8.GetString(bytes); - } - catch - { - return ""; - } - } - - /// - /// Clamps a value between a minimum and maximum. - /// - /// The value to clamp - /// Minimum value - /// Maximum value - /// The clamped value - public static double Clamp(double value, double min, double max) => Math.Max(min, Math.Min(max, value)); - - /// - /// Gets the sign of a number. - /// - /// The number - /// The sign (-1, 0, or 1) - public static int Sign(double value) => Math.Sign(value); - - /// - /// Checks if a number is even. - /// - /// The number to check - /// True if even, false otherwise - public static bool IsEven(int value) => value % 2 == 0; - - /// - /// Checks if a number is odd. - /// - /// The number to check - /// True if odd, false otherwise - public static bool IsOdd(int value) => value % 2 != 0; - - /// - /// Shuffles an array randomly. - /// - /// The array to shuffle - /// The shuffled array - public static object[] ShuffleArray(object[] arr) - { - return arr.OrderBy(x => HypnoBuiltins._random.Next()).ToArray(); - } - - /// - /// Calculates the sum of all numeric values in an array. - /// - /// The array to sum - /// The sum - public static double SumArray(object[] arr) - { - return arr.OfType().Sum(x => Convert.ToDouble(x)); - } - - /// - /// Calculates the average of all numeric values in an array. - /// - /// The array to average - /// The average - public static double AverageArray(object[] arr) - { - var nums = arr.OfType().Select(x => Convert.ToDouble(x)).ToArray(); - return nums.Length > 0 ? nums.Average() : 0.0; - } - - /// - /// Creates an array of integers from start to start + count. - /// - /// Starting number - /// Number of elements - /// Array of integers - public static object[] Range(int start, int count) - { - return Enumerable.Range(start, count).Cast().ToArray(); - } - - /// - /// Creates an array with a value repeated count times. - /// - /// The value to repeat - /// Number of repetitions - /// Array with repeated values - public static object[] Repeat(object value, int count) - { - return Enumerable.Repeat(value, count).ToArray(); - } - } -} diff --git a/HypnoScript.Runtime/Builtins/ValidationBuiltins.cs b/HypnoScript.Runtime/Builtins/ValidationBuiltins.cs deleted file mode 100644 index e82a7f8..0000000 --- a/HypnoScript.Runtime/Builtins/ValidationBuiltins.cs +++ /dev/null @@ -1,171 +0,0 @@ -using System; -using System.Text.RegularExpressions; - -namespace HypnoScript.Runtime.Builtins -{ - /// - /// Stellt Validierungsfunktionen für HypnoScript bereit. - /// - public static class ValidationBuiltins - { - /// - /// Validates email format - /// - public static bool IsValidEmail(string email) - { - if (string.IsNullOrEmpty(email)) return false; - - try - { - var regex = new Regex(@"^[^@\s]+@[^@\s]+\.[^@\s]+$"); - return regex.IsMatch(email); - } - catch - { - return false; - } - } - - /// - /// Validates URL format - /// - public static bool IsValidUrl(string url) - { - return Uri.TryCreate(url, UriKind.Absolute, out _); - } - - /// - /// Validates JSON format - /// - public static bool IsValidJson(string json) - { - if (string.IsNullOrEmpty(json)) return false; - - try - { - using var doc = System.Text.Json.JsonDocument.Parse(json); - return true; - } - catch - { - return false; - } - } - - /// - /// Validates phone number format - /// - public static bool IsValidPhoneNumber(string str) - { - if (string.IsNullOrEmpty(str)) return false; - var regex = new Regex(@"^[\+]?[1-9][\d]{0,15}$"); - return regex.IsMatch(str.Replace(" ", "").Replace("-", "").Replace("(", "").Replace(")", "")); - } - - /// - /// Validates credit card format - /// - public static bool IsValidCreditCard(string str) - { - if (string.IsNullOrEmpty(str)) return false; - var regex = new Regex(@"^[\d\s\-]{13,19}$"); - return regex.IsMatch(str); - } - - /// - /// Validates postal code format - /// - public static bool IsValidPostalCode(string str) - { - if (string.IsNullOrEmpty(str)) return false; - var regex = new Regex(@"^[\d\w\s\-]{3,10}$"); - return regex.IsMatch(str); - } - - /// - /// Validates SSN format - /// - public static bool IsValidSSN(string str) - { - if (string.IsNullOrEmpty(str)) return false; - var regex = new Regex(@"^\d{3}-?\d{2}-?\d{4}$"); - return regex.IsMatch(str); - } - - /// - /// Checks if a number is prime - /// - public static bool IsPrime(int n) - { - if (n < 2) return false; - if (n == 2) return true; - if (n % 2 == 0) return false; - - for (int i = 3; i <= Math.Sqrt(n); i += 2) - { - if (n % i == 0) return false; - } - return true; - } - - /// - /// Checks if a number is a power of 2 - /// - public static bool PowerOf2(int n) => n > 0 && (n & (n - 1)) == 0; - - /// - /// Checks if a number is a perfect square - /// - public static bool IsPerfectSquare(int n) - { - if (n < 0) return false; - int root = (int)Math.Sqrt(n); - return root * root == n; - } - - /// - /// Checks if a string is a palindrome - /// - public static bool IsPalindrome(string str) - { - if (string.IsNullOrEmpty(str)) return true; - string clean = new string(str.Where(char.IsLetterOrDigit).ToArray()).ToLower(); - return clean == new string(clean.Reverse().ToArray()); - } - - /// - /// Checks if a string is null or empty - /// - public static bool IsNullOrEmpty(string? str) => string.IsNullOrEmpty(str); - - /// - /// Checks if an object is an array - /// - public static bool IsArray(object? obj) => obj is object[]; - - /// - /// Checks if an object is a number - /// - public static bool IsNumber(object? obj) => obj is sbyte or byte or short or ushort or int or uint or long or ulong or float or double or decimal; - - /// - /// Checks if an object is a string - /// - public static bool IsString(object? obj) => obj is string; - - /// - /// Checks if an object is a boolean - /// - public static bool IsBoolean(object? obj) => obj is bool; - - /// - /// Checks if a number is even - /// - public static bool IsEven(int value) => value % 2 == 0; - - /// - /// Checks if a number is odd - /// - public static bool IsOdd(int value) => value % 2 != 0; - } -} diff --git a/HypnoScript.Runtime/HypnoBuiltins.cs b/HypnoScript.Runtime/HypnoBuiltins.cs deleted file mode 100644 index 38bee04..0000000 --- a/HypnoScript.Runtime/HypnoBuiltins.cs +++ /dev/null @@ -1,1190 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Security.Cryptography; -using System.Text.Json; -using System.Net.Http; -using System.Threading.Tasks; -using System.Threading; -using HypnoScript.Runtime.Builtins; - -namespace HypnoScript.Runtime -{ - /// - /// Stellt zentrale Builtins für HypnoScript bereit (z.B. IO, Hypnose, System, Debug). - /// - public static class HypnoBuiltins - { - /// - /// Thread-sicherer Zufallsgenerator für nicht-kryptografische Zwecke. - /// - internal static readonly Random _random = new Random(); - // For cryptographic randomness, use System.Security.Cryptography.RandomNumberGenerator - - /// - /// Eingabe-Provider für den Interpreter (kann überschrieben werden). - /// - public static Func InputProvider = prompt => { - Console.Write(prompt); - return Console.ReadLine() ?? ""; - }; - /// - /// Ausgabe-Consumer für den Interpreter (kann überschrieben werden). - /// - public static Action OutputConsumer = val => Console.WriteLine(val); - - /// - /// Gibt einen Wert an den OutputConsumer aus. - /// - public static void Observe(object? value) - { - OutputConsumer(value); - } - - /// - /// Wartet synchron für die angegebene Zeit in Millisekunden. - /// - public static void Drift(int ms) - { - System.Threading.Thread.Sleep(ms); - } - - // ===== MATHEMATISCHE FUNKTIONEN ===== - // (Moved to Builtins/MathBuiltins.cs) - - // ===== STRING-FUNKTIONEN ===== - // (Moved to Builtins/StringBuiltins.cs) - - // ===== ARRAY-FUNKTIONEN ===== - // (Moved to Builtins/ArrayBuiltins.cs) - - // ===== KONVERTIERUNGSFUNKTIONEN ===== - public static int ToInt(object? value) => Convert.ToInt32(value); - public static double ToDouble(object? value) => Convert.ToDouble(value); - public static string ToString(object? value) => value?.ToString() ?? ""; - public static bool ToBoolean(object? value) => Convert.ToBoolean(value); - public static char ToChar(object? value) => Convert.ToChar(value); - - // ===== HYPNOTISCHE SPEZIALFUNKTIONEN ===== - public static void DeepTrance(int duration = 5000) - { - Observe("Entering deep trance..."); - Drift(duration); - Observe("Emerging from trance..."); - } - - public static void HypnoticCountdown(int from = 10) - { - for (int i = from; i > 0; i--) - { - Observe($"You are feeling very sleepy... {i}"); - Drift(1000); - } - Observe("You are now in a deep hypnotic state."); - } - - public static void TranceInduction(string subjectName = "Subject") - { - Observe($"Welcome {subjectName}, you are about to enter a deep trance..."); - Drift(2000); - Observe("Take a deep breath and relax..."); - Drift(1500); - Observe("With each breath, you feel more and more relaxed..."); - Drift(1500); - Observe("Your mind is becoming clear and focused..."); - Drift(1000); - } - - public static void HypnoticVisualization(string scene = "a peaceful garden") - { - Observe($"Imagine yourself in {scene}..."); - Drift(2000); - Observe("Feel the tranquility surrounding you..."); - Drift(1500); - Observe("Every detail becomes clearer and more vivid..."); - Drift(1500); - } - - public static void ProgressiveRelaxation(int steps = 5) - { - Observe("Let's begin progressive relaxation..."); - for (int i = 1; i <= steps; i++) - { - Observe($"Step {i}: Relax your muscles deeper and deeper..."); - Drift(1500); - } - Observe("You are now completely relaxed and at peace."); - } - - public static void HypnoticSuggestion(string suggestion) - { - Observe("I will now give you a powerful suggestion..."); - Drift(1000); - Observe($"Remember this: {suggestion}"); - Drift(2000); - Observe("This suggestion will become stronger with each passing moment."); - } - - public static void TranceDeepening(int levels = 3) - { - Observe("We will now go deeper into trance..."); - for (int i = 1; i <= levels; i++) - { - Observe($"Level {i}: Going deeper..."); - Drift(2000); - } - Observe("You are now in the deepest level of trance."); - } - - // ===== ZEIT- UND DATUMSFUNKTIONEN ===== - public static int GetCurrentTime() => (int)DateTimeOffset.UtcNow.ToUnixTimeSeconds(); - public static string GetCurrentDate() => DateTime.Now.ToString("yyyy-MM-dd"); - public static string GetCurrentTimeString() => DateTime.Now.ToString("HH:mm:ss"); - public static string GetCurrentDateTime() => DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); - - // ===== SYSTEM-FUNKTIONEN ===== - public static void ClearScreen() - { - Console.Clear(); - } - - public static void Beep(int frequency = 800, int duration = 200) - { -#if WINDOWS - Console.Beep(frequency, duration); -#else - // Fallback für nicht-Windows Plattformen - System.Threading.Thread.Sleep(duration); -#endif - } - - public static string GetEnvironmentVariable(string name) - { - return Environment.GetEnvironmentVariable(name) ?? ""; - } - - public static void Exit(int code = 0) - { - Environment.Exit(code); - } - - // ===== DEBUGGING-FUNKTIONEN ===== - public static void DebugPrint(object? value) - { - Console.WriteLine($"[DEBUG] {value}"); - } - - public static void DebugPrintType(object? value) - { - Console.WriteLine($"[DEBUG] Type: {value?.GetType().Name ?? "null"}"); - } - - // ===== ERWEITERTE HYPNOTISCHE FUNKTIONEN (Runtime) ===== - public static void HypnoticBreathing(int cycles = 5) - { - Observe("Let's practice hypnotic breathing..."); - for (int i = 1; i <= cycles; i++) - { - Observe($"Cycle {i}: Breathe in deeply..."); - Drift(2000); - Observe("Hold your breath..."); - Drift(1000); - Observe("Now exhale slowly..."); - Drift(2000); - } - Observe("You are now in a state of perfect calm."); - } - - public static void HypnoticAnchoring(string anchor = "peaceful") - { - Observe($"I will now create a powerful anchor for '{anchor}'..."); - Drift(1500); - Observe("Every time you think of this anchor, you will feel this way..."); - Drift(2000); - Observe($"Your '{anchor}' anchor is now established."); - } - - public static void HypnoticRegression(int age = 10) - { - Observe($"We will now travel back in time to when you were {age} years old..."); - Drift(3000); - Observe("You can see yourself as a child..."); - Drift(2000); - Observe("Feel the memories and emotions of that time..."); - Drift(2000); - Observe("You are now experiencing your past self."); - } - - public static void HypnoticFutureProgression(int years = 5) - { - Observe($"Let's travel forward {years} years into your future..."); - Drift(3000); - Observe("You can see your future self..."); - Drift(2000); - Observe("Feel the wisdom and experience of your future..."); - Drift(2000); - Observe("You are now connected to your future potential."); - } - - // ===== DATEI- UND VERZEICHNIS-OPERATIONEN ===== - // (Moved to Builtins/FileBuiltins.cs) - - // ===== JSON-VERARBEITUNG ===== - public static string ToJson(object? obj) - { - try - { - return JsonSerializer.Serialize(obj, new JsonSerializerOptions { WriteIndented = true }); - } - catch (Exception ex) - { - Observe($"Error serializing to JSON: {ex.Message}"); - return "{}"; - } - } - - public static object? FromJson(string json) - { - try - { - return JsonSerializer.Deserialize(json); - } - catch (Exception ex) - { - Observe($"Error deserializing JSON: {ex.Message}"); - return null; - } - } - - // ===== ERWEITERTE MATHEMATISCHE FUNKTIONEN ===== - public static double Factorial(int n) - { - if (n < 0) return double.NaN; - if (n <= 1) return 1; - double result = 1; - for (int i = 2; i <= n; i++) - result *= i; - return result; - } - - public static double GCD(double a, double b) - { - a = Math.Abs(a); - b = Math.Abs(b); - while (b != 0) - { - var temp = b; - b = a % b; - a = temp; - } - return a; - } - - public static double LCM(double a, double b) - { - return Math.Abs(a * b) / GCD(a, b); - } - - public static double DegreesToRadians(double degrees) => degrees * Math.PI / 180.0; - public static double RadiansToDegrees(double radians) => radians * 180.0 / Math.PI; - - public static double Asin(double x) => Math.Asin(x) * 180.0 / Math.PI; - public static double Acos(double x) => Math.Acos(x) * 180.0 / Math.PI; - public static double Atan(double x) => Math.Atan(x) * 180.0 / Math.PI; - public static double Atan2(double y, double x) => Math.Atan2(y, x) * 180.0 / Math.PI; - - // ===== ERWEITERTE STRING-FUNKTIONEN ===== - public static string Reverse(string str) - { - var chars = str.ToCharArray(); - Array.Reverse(chars); - return new string(chars); - } - - public static string Capitalize(string str) - { - if (string.IsNullOrEmpty(str)) return str; - return char.ToUpper(str[0]) + str.Substring(1).ToLower(); - } - - public static string TitleCase(string str) - { - if (string.IsNullOrEmpty(str)) return str; - var words = str.Split(' '); - for (int i = 0; i < words.Length; i++) - { - if (!string.IsNullOrEmpty(words[i])) - words[i] = Capitalize(words[i]); - } - return string.Join(" ", words); - } - - public static int CountOccurrences(string str, string substring) - { - if (string.IsNullOrEmpty(str) || string.IsNullOrEmpty(substring)) - return 0; - - int count = 0; - int index = 0; - while ((index = str.IndexOf(substring, index)) != -1) - { - count++; - index += substring.Length; - } - return count; - } - - public static string RemoveWhitespace(string str) - { - return string.Join("", str.Where(c => !char.IsWhiteSpace(c))); - } - - // ===== ERWEITERTE ARRAY-FUNKTIONEN ===== - public static object[] ArrayReverse(object[] arr) - { - var result = new object[arr.Length]; - Array.Copy(arr, result, arr.Length); - Array.Reverse(result); - return result; - } - - public static object[] ArraySort(object[] arr) - { - var result = new object[arr.Length]; - Array.Copy(arr, result, arr.Length); - Array.Sort(result); - return result; - } - - public static object[] ArrayUnique(object[] arr) - { - return arr.Distinct().ToArray(); - } - - public static object[] ArrayFilter(object[] arr, Func predicate) - { - return arr.Where(predicate).ToArray(); - } - - // ===== KRYPTOLOGISCHE FUNKTIONEN ===== - public static string HashMD5(string input) - { - using (var md5 = MD5.Create()) - { - var hash = md5.ComputeHash(Encoding.UTF8.GetBytes(input)); - return Convert.ToHexString(hash).ToLower(); - } - } - - public static string HashSHA256(string input) - { - using (var sha256 = SHA256.Create()) - { - var hash = sha256.ComputeHash(Encoding.UTF8.GetBytes(input)); - return Convert.ToHexString(hash).ToLower(); - } - } - - public static string Base64Encode(string input) - { - var bytes = Encoding.UTF8.GetBytes(input); - return Convert.ToBase64String(bytes); - } - - public static string Base64Decode(string input) - { - try - { - var bytes = Convert.FromBase64String(input); - return Encoding.UTF8.GetString(bytes); - } - catch - { - return ""; - } - } - - // ===== ERWEITERTE ZEIT- UND DATUMSFUNKTIONEN ===== - public static string FormatDateTime(string format = "yyyy-MM-dd HH:mm:ss") - { - return DateTime.Now.ToString(format); - } - - public static int GetDayOfWeek() => (int)DateTime.Now.DayOfWeek; - public static int GetDayOfYear() => DateTime.Now.DayOfYear; - public static bool IsLeapYear(int year) => DateTime.IsLeapYear(year); - public static int GetDaysInMonth(int year, int month) => DateTime.DaysInMonth(year, month); - - // ===== ERWEITERTE SYSTEM-FUNKTIONEN ===== - public static string GetCurrentDirectory() => Environment.CurrentDirectory; - public static string GetMachineName() => Environment.MachineName; - public static string GetUserName() => Environment.UserName; - public static string GetOSVersion() => Environment.OSVersion.ToString(); - public static int GetProcessorCount() => Environment.ProcessorCount; - public static long GetWorkingSet() => Environment.WorkingSet; - - public static void PlaySound(int frequency = 800, int duration = 200) - { -#if WINDOWS - Console.Beep(frequency, duration); -#else - // Fallback für nicht-Windows Plattformen - System.Threading.Thread.Sleep(duration); -#endif - } - - public static void Vibrate(int duration = 1000) - { - // Simuliere Vibration durch mehrere Beeps - var startTime = DateTime.Now; - while ((DateTime.Now - startTime).TotalMilliseconds < duration) - { -#if WINDOWS - Console.Beep(200, 50); -#else - // Fallback für nicht-Windows Plattformen - System.Threading.Thread.Sleep(50); -#endif - System.Threading.Thread.Sleep(50); - } - } - - public static void DebugPrintMemory() - { - var process = System.Diagnostics.Process.GetCurrentProcess(); - Observe($"Memory Usage: {process.WorkingSet64 / 1024 / 1024} MB"); - } - - public static void DebugPrintStackTrace() - { - Observe("Stack Trace:"); - Observe(Environment.StackTrace); - } - - public static void DebugPrintEnvironment() - { - Observe("Environment Variables:"); - foreach (var env in Environment.GetEnvironmentVariables().Cast().Take(10)) - { - Observe($" {env.Key} = {env.Value}"); - } - } - - // ===== NEUE ENTERPRISE-FEATURES ===== - - // Machine Learning Funktionen - public static double LinearRegression(object[] x, object[] y) - { - if (x.Length != y.Length || x.Length < 2) return double.NaN; - - var n = x.Length; - var sumX = 0.0; - var sumY = 0.0; - var sumXY = 0.0; - var sumX2 = 0.0; - - for (int i = 0; i < n; i++) - { - var xi = Convert.ToDouble(x[i]); - var yi = Convert.ToDouble(y[i]); - sumX += xi; - sumY += yi; - sumXY += xi * yi; - sumX2 += xi * xi; - } - - var slope = (n * sumXY - sumX * sumY) / (n * sumX2 - sumX * sumX); - return slope; - } - - public static double CalculateMean(object[] values) - { - if (values.Length == 0) return double.NaN; - var sum = values.Sum(v => Convert.ToDouble(v)); - return sum / values.Length; - } - - public static double CalculateStandardDeviation(object[] values) - { - if (values.Length < 2) return double.NaN; - var mean = CalculateMean(values); - var sumSquaredDiff = values.Sum(v => Math.Pow(Convert.ToDouble(v) - mean, 2)); - return Math.Sqrt(sumSquaredDiff / (values.Length - 1)); - } - - // Datenbank-ähnliche Funktionen - public static Dictionary CreateRecord(string[] keys, object[] values) - { - var record = new Dictionary(); - for (int i = 0; i < Math.Min(keys.Length, values.Length); i++) - { - record[keys[i]] = values[i]; - } - return record; - } - - public static object? GetRecordValue(Dictionary record, string key) - { - return record.TryGetValue(key, out var value) ? value : null; - } - - public static void SetRecordValue(Dictionary record, string key, object value) - { - record[key] = value; - } - - // Erweiterte hypnotische Funktionen - public static void HypnoticPatternMatching(string pattern) - { - Observe($"I will now establish a pattern matching system for '{pattern}'..."); - Drift(2000); - Observe("Your mind will automatically recognize this pattern..."); - Drift(1500); - Observe("Every time you encounter this pattern, you will respond automatically..."); - Drift(2000); - Observe($"The '{pattern}' pattern is now deeply embedded in your subconscious."); - } - - public static void HypnoticTimeDilation(double factor = 2.0) - { - Observe($"I will now alter your perception of time by a factor of {factor}..."); - Drift(3000); - Observe("Time will feel different to you now..."); - Drift(2000); - Observe("Minutes will feel like hours, or hours like minutes..."); - Drift(2000); - Observe("Your time perception has been successfully modified."); - } - - public static void HypnoticMemoryEnhancement() - { - Observe("I will now enhance your memory capabilities..."); - Drift(2000); - Observe("Your ability to remember and recall information will improve..."); - Drift(2000); - Observe("You will find it easier to learn and retain new knowledge..."); - Drift(2000); - Observe("Your memory enhancement is now active."); - } - - public static void HypnoticCreativityBoost() - { - Observe("I will now unlock your creative potential..."); - Drift(2000); - Observe("Your imagination will become more vivid and active..."); - Drift(2000); - Observe("Creative solutions will come to you more easily..."); - Drift(2000); - Observe("Your creativity is now enhanced."); - } - - // Performance-Monitoring - public static Dictionary GetPerformanceMetrics() - { - var process = System.Diagnostics.Process.GetCurrentProcess(); - var metrics = new Dictionary - { - ["cpu_time"] = process.TotalProcessorTime.TotalMilliseconds, - ["memory_usage"] = process.WorkingSet64, - ["thread_count"] = process.Threads.Count, - ["start_time"] = process.StartTime.ToString(), - ["uptime"] = (DateTime.Now - process.StartTime).TotalSeconds - }; - return metrics; - } - - // Erweiterte Validierungsfunktionen - public static bool IsValidEmail(string email) - { - try - { - var addr = new System.Net.Mail.MailAddress(email); - return addr.Address == email; - } - catch - { - return false; - } - } - - public static bool IsValidUrl(string url) - { - return Uri.TryCreate(url, UriKind.Absolute, out _); - } - - public static bool IsValidJson(string json) - { - try - { - JsonSerializer.Deserialize(json); - return true; - } - catch - { - return false; - } - } - - // Erweiterte Formatierungsfunktionen - public static string FormatNumber(double number, int decimals = 2) - { - return number.ToString($"F{decimals}"); - } - - public static string FormatCurrency(double amount, string currency = "USD") - { - return $"{currency} {amount:F2}"; - } - - public static string FormatPercentage(double value) - { - return $"{value:F2}%"; - } - - // Erweiterte Array-Operationen - public static object[] ArrayMap(object[] arr, Func mapper) - { - return arr.Select(mapper).ToArray(); - } - - public static object ArrayReduce(object[] arr, Func reducer, object initial) - { - return arr.Aggregate(initial, reducer); - } - - public static object[] ArrayFlatten(object[] arr) - { - var result = new List(); - foreach (var item in arr) - { - if (item is object[] subArray) - result.AddRange(subArray); - else - result.Add(item); - } - return result.ToArray(); - } - - // Erweiterte String-Operationen - public static string[] StringSplitByLength(string str, int maxLength) - { - var result = new List(); - for (int i = 0; i < str.Length; i += maxLength) - { - var length = Math.Min(maxLength, str.Length - i); - result.Add(str.Substring(i, length)); - } - return result.ToArray(); - } - - public static string StringRotate(string str, int positions) - { - if (string.IsNullOrEmpty(str)) return str; - positions = positions % str.Length; - if (positions < 0) positions += str.Length; - return str.Substring(positions) + str.Substring(0, positions); - } - - public static string StringShuffle(string str) - { - var chars = str.ToCharArray(); - for (int i = chars.Length - 1; i > 0; i--) - { - int j = _random.Next(i + 1); - var temp = chars[i]; - chars[i] = chars[j]; - chars[j] = temp; - } - return new string(chars); - } - - // ===== WEITERE UTILITY-FUNKTIONEN ===== - public static double Clamp(double value, double min, double max) => Math.Max(min, Math.Min(max, value)); - public static int Sign(double value) => Math.Sign(value); - public static bool IsEven(int value) => value % 2 == 0; - public static bool IsOdd(int value) => value % 2 != 0; - public static object[] ShuffleArray(object[] arr) - { - return arr.OrderBy(x => _random.Next()).ToArray(); - } - public static double SumArray(object[] arr) - { - return arr.OfType().Sum(x => Convert.ToDouble(x)); - } - public static double AverageArray(object[] arr) - { - var nums = arr.OfType().Select(x => Convert.ToDouble(x)).ToArray(); - return nums.Length > 0 ? nums.Average() : 0.0; - } - public static object[] Range(int start, int count) - { - return Enumerable.Range(start, count).Cast().ToArray(); - } - public static object[] Repeat(object value, int count) - { - return Enumerable.Repeat(value, count).ToArray(); - } - public static void Swap(object[] arr, int i, int j) - { - var tmp = arr[i]; - arr[i] = arr[j]; - arr[j] = tmp; - } - public static object[][] ChunkArray(object[] arr, int chunkSize) - { - return arr.Select((x, i) => new { x, i }) - .GroupBy(x => x.i / chunkSize) - .Select(g => g.Select(v => v.x).ToArray()) - .ToArray(); - } - - // ===== WEITERE UTILITY-FUNKTIONEN (Ergänzung) ===== - public static double ArraySum(object[] arr) => arr.OfType().Sum(x => Convert.ToDouble(x)); - public static object? ArrayMin(object[] arr) => arr.Length == 0 ? null : arr.Min(); - public static object? ArrayMax(object[] arr) => arr.Length == 0 ? null : arr.Max(); - public static int ArrayCount(object[] arr, object? value) => arr.Count(x => Equals(x, value)); - public static object[] ArrayRemove(object[] arr, object? value) => arr.Where(x => !Equals(x, value)).ToArray(); - public static object[] ArrayDistinct(object[] arr) => arr.Distinct().ToArray(); - - public static bool IsNullOrEmpty(string? str) => string.IsNullOrEmpty(str); - public static string RepeatString(string str, int n) => string.Concat(Enumerable.Repeat(str, n)); - public static string ReverseWords(string str) => string.Join(" ", str.Split(' ').Reverse()); - public static string Truncate(string str, int length) => str.Length <= length ? str : str.Substring(0, length); - public static string RemoveDigits(string str) => new string(str.Where(c => !char.IsDigit(c)).ToArray()); - - public static bool IsPrime(int n) - { - if (n <= 1) return false; - if (n == 2) return true; - if (n % 2 == 0) return false; - int boundary = (int)Math.Floor(Math.Sqrt(n)); - for (int i = 3; i <= boundary; i += 2) - if (n % i == 0) return false; - return true; - } - public static System.Numerics.BigInteger FactorialBig(int n) - { - System.Numerics.BigInteger result = 1; - for (int i = 2; i <= n; i++) result *= i; - return result; - } - public static string ToHex(long n) => n.ToString("X"); - public static string ToBinary(long n) => Convert.ToString(n, 2); - public static int ParseInt(string str) - { - int.TryParse(str, out int result); - return result; - } - - public static Dictionary GetEnvVars() => Environment.GetEnvironmentVariables().Cast().ToDictionary(e => (string)e.Key, e => e.Value as string ?? ""); - public static string GetTempPath() => System.IO.Path.GetTempPath(); - public static long GetTickCount() => Environment.TickCount64; - public static void Sleep(int ms) => System.Threading.Thread.Sleep(ms); - - public static string AddDays(string date, int n) => DateTime.Parse(date).AddDays(n).ToString("yyyy-MM-dd"); - public static string AddMonths(string date, int n) => DateTime.Parse(date).AddMonths(n).ToString("yyyy-MM-dd"); - public static string AddYears(string date, int n) => DateTime.Parse(date).AddYears(n).ToString("yyyy-MM-dd"); - public static string ParseDate(string str) => DateTime.Parse(str).ToString("yyyy-MM-dd"); - - public static bool IsArray(object? obj) => obj is object[]; - public static bool IsNumber(object? obj) => obj is sbyte or byte or short or ushort or int or uint or long or ulong or float or double or decimal; - public static bool IsString(object? obj) => obj is string; - public static bool IsBoolean(object? obj) => obj is bool; - - // ===== DICTIONARY-UTILITIES ===== - public static Dictionary CreateDictionary() => new(); - public static string[] DictionaryKeys(Dictionary dict) => dict.Keys.ToArray(); - public static object[] DictionaryValues(Dictionary dict) => dict.Values.ToArray(); - public static bool DictionaryContainsKey(Dictionary dict, string key) => dict.ContainsKey(key); - public static object? DictionaryGet(Dictionary dict, string key, object? defaultValue = null) => dict.TryGetValue(key, out var value) ? value : defaultValue; - public static void DictionarySet(Dictionary dict, string key, object value) => dict[key] = value; - public static bool DictionaryRemove(Dictionary dict, string key) => dict.Remove(key); - public static int DictionaryCount(Dictionary dict) => dict.Count; - - // ===== ERWEITERTE STRING-UTILITIES ===== - public static string Insert(string str, int index, string value) => str.Insert(index, value); - public static string Remove(string str, int start, int count) => str.Remove(start, count); - public static int Compare(string str1, string str2) => string.Compare(str1, str2); - public static bool EqualsIgnoreCase(string str1, string str2) => string.Equals(str1, str2, StringComparison.OrdinalIgnoreCase); - public static bool IsPalindrome(string str) - { - var clean = new string(str.Where(char.IsLetterOrDigit).ToArray()).ToLower(); - return clean == new string(clean.Reverse().ToArray()); - } - public static int CountWords(string str) => str.Split(new[] { ' ', '\t', '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries).Length; - public static string ExtractNumbers(string str) => new string(str.Where(char.IsDigit).ToArray()); - public static string ExtractLetters(string str) => new string(str.Where(char.IsLetter).ToArray()); - - // ===== ERWEITERTE ARRAY-UTILITIES ===== - public static object[] ArrayInsert(object[] arr, int index, object value) - { - if (arr == null) - { - Observe("Error: Array is null."); - return Array.Empty(); - } - if (index < 0 || index > arr.Length) - { - Observe($"Error: Array insert index {index} out of bounds (length: {arr.Length})."); - return arr; - } - var result = new object[arr.Length + 1]; - Array.Copy(arr, 0, result, 0, index); - result[index] = value; - Array.Copy(arr, index, result, index + 1, arr.Length - index); - return result; - } - public static object[] ArrayRemoveAt(object[] arr, int index) - { - if (arr == null) - { - Observe("Error: Array is null."); - return Array.Empty(); - } - if (index < 0 || index >= arr.Length) - { - Observe($"Error: Array remove index {index} out of bounds (length: {arr.Length})."); - return arr; - } - var result = new object[arr.Length - 1]; - Array.Copy(arr, 0, result, 0, index); - Array.Copy(arr, index + 1, result, index, arr.Length - index - 1); - return result; - } - public static void ArrayClear(object[] arr) => Array.Clear(arr, 0, arr.Length); - public static object[] ArrayCopy(object[] arr) - { - var result = new object[arr.Length]; - Array.Copy(arr, result, arr.Length); - return result; - } - public static object[] ArrayResize(object[] arr, int newSize) - { - var result = new object[newSize]; - Array.Copy(arr, result, Math.Min(arr.Length, newSize)); - return result; - } - public static void ArrayFill(object[] arr, object value) => Array.Fill(arr, value); - public static int ArrayIndexOf(object[] arr, object value, int startIndex) => Array.IndexOf(arr, value, startIndex); - public static int ArrayLastIndexOf(object[] arr, object value) => Array.LastIndexOf(arr, value); - public static object[] ArraySubArray(object[] arr, int start, int end) - { - var length = end - start + 1; - var result = new object[length]; - Array.Copy(arr, start, result, 0, length); - return result; - } - public static object[] ArrayRotate(object[] arr, int positions) - { - var result = new object[arr.Length]; - for (int i = 0; i < arr.Length; i++) - { - var newIndex = (i + positions) % arr.Length; - if (newIndex < 0) newIndex += arr.Length; - result[newIndex] = arr[i]; - } - return result; - } - public static object[] ArrayShuffle(object[] arr, int seed) - { - var rnd = new Random(seed); - return arr.OrderBy(x => rnd.Next()).ToArray(); - } - public static object[][] ArrayPartition(object[] arr, Func predicate) - { - var trueItems = arr.Where(predicate).ToArray(); - var falseItems = arr.Where(x => !predicate(x)).ToArray(); - return new[] { trueItems, falseItems }; - } - - // ===== MATHEMATISCHE ERWEITERUNGEN ===== - public static double RoundToDecimal(double x, int decimals) => Math.Round(x, decimals); - public static double CeilingToDecimal(double x, int decimals) => Math.Ceiling(x * Math.Pow(10, decimals)) / Math.Pow(10, decimals); - public static double FloorToDecimal(double x, int decimals) => Math.Floor(x * Math.Pow(10, decimals)) / Math.Pow(10, decimals); - public static double Modulo(double a, double b) => a % b; - public static bool PowerOf2(int n) => n > 0 && (n & (n - 1)) == 0; - public static int NextPowerOf2(int n) - { - if (n <= 1) return 1; - n--; - n |= n >> 1; - n |= n >> 2; - n |= n >> 4; - n |= n >> 8; - n |= n >> 16; - return n + 1; - } - public static bool IsPerfectSquare(int n) - { - var sqrt = (int)Math.Sqrt(n); - return sqrt * sqrt == n; - } - public static int SqrtInt(int n) => (int)Math.Sqrt(n); - public static int GCDArray(object[] arr) - { - var nums = arr.OfType().Select(x => Convert.ToInt32(x)).ToArray(); - if (nums.Length == 0) return 0; - var result = nums[0]; - for (int i = 1; i < nums.Length; i++) - result = (int)GCD(result, nums[i]); - return result; - } - public static int LCMArray(object[] arr) - { - var nums = arr.OfType().Select(x => Convert.ToInt32(x)).ToArray(); - if (nums.Length == 0) return 0; - var result = nums[0]; - for (int i = 1; i < nums.Length; i++) - result = (int)LCM(result, nums[i]); - return result; - } - public static int SumOfDigits(long n) => n.ToString().Sum(c => c - '0'); - public static long ReverseNumber(long n) => long.Parse(new string(n.ToString().Reverse().ToArray())); - - // ===== DATEI/SYSTEM-ERWEITERUNGEN ===== - public static void FileCopy(string source, string dest) - { - try - { - System.IO.File.Copy(source, dest); - Observe($"File copied from '{source}' to '{dest}'."); - } - catch (Exception ex) - { - Observe($"Error copying file from '{source}' to '{dest}': {ex.Message}"); - } - } - public static void FileMove(string source, string dest) - { - try - { - System.IO.File.Move(source, dest); - Observe($"File moved from '{source}' to '{dest}'."); - } - catch (Exception ex) - { - Observe($"Error moving file from '{source}' to '{dest}': {ex.Message}"); - } - } - public static void FileDelete(string path) - { - try - { - System.IO.File.Delete(path); - Observe($"File '{path}' deleted successfully."); - } - catch (Exception ex) - { - Observe($"Error deleting file '{path}': {ex.Message}"); - } - } - public static Dictionary GetFileInfo(string path) - { - var info = new System.IO.FileInfo(path); - return new Dictionary - { - ["Name"] = info.Name, - ["FullName"] = info.FullName, - ["Length"] = info.Length, - ["CreationTime"] = info.CreationTime.ToString("yyyy-MM-dd HH:mm:ss"), - ["LastWriteTime"] = info.LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss"), - ["Extension"] = info.Extension, - ["Exists"] = info.Exists - }; - } - public static bool IsFileReadOnly(string path) => (System.IO.File.GetAttributes(path) & System.IO.FileAttributes.ReadOnly) != 0; - public static void SetFileReadOnly(string path, bool readOnly) - { - var attributes = System.IO.File.GetAttributes(path); - if (readOnly) - attributes |= System.IO.FileAttributes.ReadOnly; - else - attributes &= ~System.IO.FileAttributes.ReadOnly; - System.IO.File.SetAttributes(path, attributes); - } - public static string GetFileCreationTime(string path) => System.IO.File.GetCreationTime(path).ToString("yyyy-MM-dd HH:mm:ss"); - public static string GetFileLastWriteTime(string path) => System.IO.File.GetLastWriteTime(path).ToString("yyyy-MM-dd HH:mm:ss"); - public static double GetFileSizeMB(string path) => new System.IO.FileInfo(path).Length / (1024.0 * 1024.0); - public static string GetFileNameWithoutExtension(string path) => System.IO.Path.GetFileNameWithoutExtension(path); - public static string CombinePath(string path1, string path2) => System.IO.Path.Combine(path1, path2); - - // ===== NETZWERK/WEB-UTILITIES ===== - // (Moved to Builtins/NetworkBuiltins.cs) - - // ===== VALIDIERUNG/FORMATIERUNG ===== - public static bool IsValidPhoneNumber(string str) - { - var clean = new string(str.Where(char.IsDigit).ToArray()); - return clean.Length >= 10 && clean.Length <= 15; - } - public static bool IsValidCreditCard(string str) - { - var clean = new string(str.Where(char.IsDigit).ToArray()); - return clean.Length >= 13 && clean.Length <= 19; - } - public static bool IsValidPostalCode(string str) - { - var clean = new string(str.Where(char.IsLetterOrDigit).ToArray()); - return clean.Length >= 4 && clean.Length <= 10; - } - public static bool IsValidSSN(string str) - { - var clean = new string(str.Where(char.IsDigit).ToArray()); - return clean.Length == 9; - } - public static string FormatPhoneNumber(string str) - { - var clean = new string(str.Where(char.IsDigit).ToArray()); - if (clean.Length == 10) - return $"({clean.Substring(0, 3)}) {clean.Substring(3, 3)}-{clean.Substring(6)}"; - return str; - } - public static string FormatCreditCard(string str) - { - var clean = new string(str.Where(char.IsDigit).ToArray()); - if (clean.Length >= 4) - return new string('*', clean.Length - 4) + clean.Substring(clean.Length - 4); - return str; - } - public static string MaskString(string str, char maskChar, int start, int end) - { - if (start >= str.Length || end < start) return str; - var chars = str.ToCharArray(); - for (int i = start; i <= Math.Min(end, str.Length - 1); i++) - chars[i] = maskChar; - return new string(chars); - } - public static string GenerateRandomString(int length) - { - const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; - return new string(Enumerable.Repeat(chars, length).Select(s => s[_random.Next(s.Length)]).ToArray()); - } - public static string GenerateUUID() => Guid.NewGuid().ToString(); - - // ===== ZEIT/DATUM-ERWEITERUNGEN ===== - public static string GetTimeZone() => TimeZoneInfo.Local.DisplayName; - public static string ConvertTimeZone(string date, string fromZone, string toZone) - { - try - { - var dt = DateTime.Parse(date); - var fromTz = TimeZoneInfo.FindSystemTimeZoneById(fromZone); - var toTz = TimeZoneInfo.FindSystemTimeZoneById(toZone); - var converted = TimeZoneInfo.ConvertTime(dt, fromTz, toTz); - return converted.ToString("yyyy-MM-dd HH:mm:ss"); - } - catch { return date; } - } - public static int GetWeekOfYear(string date) - { - var dt = DateTime.Parse(date); - var calendar = System.Globalization.CultureInfo.InvariantCulture.Calendar; - return calendar.GetWeekOfYear(dt, System.Globalization.CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday); - } - public static int GetQuarter(string date) - { - var dt = DateTime.Parse(date); - return (dt.Month - 1) / 3 + 1; - } - public static bool IsWeekend(string date) - { - var dt = DateTime.Parse(date); - return dt.DayOfWeek == DayOfWeek.Saturday || dt.DayOfWeek == DayOfWeek.Sunday; - } - public static bool IsBusinessDay(string date) => !IsWeekend(date); - public static string AddBusinessDays(string date, int days) - { - var dt = DateTime.Parse(date); - var added = 0; - while (added < days) - { - dt = dt.AddDays(1); - if (IsBusinessDay(dt.ToString("yyyy-MM-dd"))) - added++; - } - return dt.ToString("yyyy-MM-dd"); - } - public static int GetDaysBetween(string date1, string date2) - { - var dt1 = DateTime.Parse(date1); - var dt2 = DateTime.Parse(date2); - return Math.Abs((dt2 - dt1).Days); - } - public static int GetAge(string birthDate) - { - var birth = DateTime.Parse(birthDate); - var today = DateTime.Today; - var age = today.Year - birth.Year; - if (birth.Date > today.AddYears(-age)) age--; - return age; - } - public static bool IsLeapDay(string date) - { - var dt = DateTime.Parse(date); - return dt.Month == 2 && dt.Day == 29; - } - - // ===== PERFORMANCE/DEBUG-UTILITIES ===== - public static long GetMemoryUsage() => GC.GetTotalMemory(false); - public static double GetCPUUsage() - { - // Vereinfachte Implementierung - in der Praxis würde man PerformanceCounter verwenden - return Environment.ProcessorCount * 10.0; // Simuliert 10% pro Core - } - public static Dictionary GetProcessInfo() - { - var process = System.Diagnostics.Process.GetCurrentProcess(); - return new Dictionary - { - ["Id"] = process.Id, - ["ProcessName"] = process.ProcessName, - ["WorkingSet"] = process.WorkingSet64, - ["PrivateMemorySize"] = process.PrivateMemorySize64, - ["VirtualMemorySize"] = process.VirtualMemorySize64, - ["StartTime"] = process.StartTime.ToString("yyyy-MM-dd HH:mm:ss") - }; - } - public static Dictionary GetSystemInfo() - { - return new Dictionary - { - ["MachineName"] = Environment.MachineName, - ["OSVersion"] = Environment.OSVersion.ToString(), - ["ProcessorCount"] = Environment.ProcessorCount, - ["WorkingSet"] = Environment.WorkingSet, - ["SystemPageSize"] = Environment.SystemPageSize, - ["TickCount"] = Environment.TickCount64 - }; - } - public static double Benchmark(Func func, int iterations) - { - var sw = System.Diagnostics.Stopwatch.StartNew(); - for (int i = 0; i < iterations; i++) - func(); - return sw.Elapsed.TotalMilliseconds; - } - public static string[] GetCallStack() - { - return new System.Diagnostics.StackTrace(true).GetFrames() - .Select(f => f.ToString()) - .ToArray(); - } - public static Dictionary GetExceptionInfo(Exception ex) - { - return new Dictionary - { - ["Message"] = ex.Message, - ["Type"] = ex.GetType().Name, - ["StackTrace"] = ex.StackTrace ?? "", - ["Source"] = ex.Source ?? "" - }; - } - public static void Log(string message, string level = "INFO") - { - var timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); - Console.WriteLine($"[{timestamp}] [{level}] {message}"); - } - public static void Trace(string message) => Log(message, "TRACE"); - } -} diff --git a/HypnoScript.Runtime/HypnoScript.Runtime.csproj b/HypnoScript.Runtime/HypnoScript.Runtime.csproj deleted file mode 100644 index d29482c..0000000 --- a/HypnoScript.Runtime/HypnoScript.Runtime.csproj +++ /dev/null @@ -1,20 +0,0 @@ - - - - net8.0 - enable - enable - bin\Debug\net8.0\HypnoScript.Runtime.xml - - - - - - - - - - - - - diff --git a/HypnoScript.csproj b/HypnoScript.csproj deleted file mode 100644 index c7ea07c..0000000 --- a/HypnoScript.csproj +++ /dev/null @@ -1,13 +0,0 @@ - - - - Exe - net9.0 - HypnoScript - enable - enable - true - true - - - diff --git a/HypnoScript.sln b/HypnoScript.sln deleted file mode 100644 index b6c90aa..0000000 --- a/HypnoScript.sln +++ /dev/null @@ -1,45 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.12.35527.113 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HypnoScript.Core", "HypnoScript.Core\HypnoScript.Core.csproj", "{D59609C1-6734-47E2-87C9-4C943FDBC392}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HypnoScript.LexerParser", "HypnoScript.LexerParser\HypnoScript.LexerParser.csproj", "{A1234567-89AB-CDEF-0123-456789ABCDEF}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HypnoScript.Compiler", "HypnoScript.Compiler\HypnoScript.Compiler.csproj", "{B1234567-89AB-CDEF-0123-456789ABCDEF}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HypnoScript.Runtime", "HypnoScript.Runtime\HypnoScript.Runtime.csproj", "{C1234567-89AB-CDEF-0123-456789ABCDEF}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HypnoScript.CLI", "HypnoScript.CLI\HypnoScript.CLI.csproj", "{D1234567-89AB-CDEF-0123-456789ABCDEF}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {D59609C1-6734-47E2-87C9-4C943FDBC392}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D59609C1-6734-47E2-87C9-4C943FDBC392}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D59609C1-6734-47E2-87C9-4C943FDBC392}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D59609C1-6734-47E2-87C9-4C943FDBC392}.Release|Any CPU.Build.0 = Release|Any CPU - {A1234567-89AB-CDEF-0123-456789ABCDEF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A1234567-89AB-CDEF-0123-456789ABCDEF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A1234567-89AB-CDEF-0123-456789ABCDEF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A1234567-89AB-CDEF-0123-456789ABCDEF}.Release|Any CPU.Build.0 = Release|Any CPU - {B1234567-89AB-CDEF-0123-456789ABCDEF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B1234567-89AB-CDEF-0123-456789ABCDEF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B1234567-89AB-CDEF-0123-456789ABCDEF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B1234567-89AB-CDEF-0123-456789ABCDEF}.Release|Any CPU.Build.0 = Release|Any CPU - {C1234567-89AB-CDEF-0123-456789ABCDEF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C1234567-89AB-CDEF-0123-456789ABCDEF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C1234567-89AB-CDEF-0123-456789ABCDEF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C1234567-89AB-CDEF-0123-456789ABCDEF}.Release|Any CPU.Build.0 = Release|Any CPU - {D1234567-89AB-CDEF-0123-456789ABCDEF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D1234567-89AB-CDEF-0123-456789ABCDEF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D1234567-89AB-CDEF-0123-456789ABCDEF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D1234567-89AB-CDEF-0123-456789ABCDEF}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e852fa9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Kink Development Group + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 937580c..2c02d64 100644 --- a/README.md +++ b/README.md @@ -1,188 +1,324 @@ -# HypnoScript v1.0.0 – Die hypnotische Programmiersprache +# HypnoScript – Rust Implementation -**HypnoScript** ist eine moderne, esoterische Programmiersprache mit TypeScript-inspirierter Syntax und hypnotischem Flair. Sie ist Turing-vollständig, bietet eine umfangreiche Standardbibliothek und richtet sich an Entwickler, die Spaß an innovativen Sprachkonzepten haben. +**HypnoScript** ist eine hypnotisch angehauchte Programmiersprache mit eigener Syntax (`Focus { ... } Relax`). +Die komplette Laufzeitumgebung, der Compiler und die Kommandozeilen-Tools wurden aus C# nach Rust +portiert und ab Version 1.0 ausschließlich in Rust weiterentwickelt. --- -## 🚀 Features (v1.0.0) +## 🚀 Highlights -- **TypeScript-ähnliche Syntax**: `Focus { ... } Relax`, `induce`, `suggestion`, `session`, `tranceify` -- **150+ Builtins**: Mathe, Strings, Arrays, System, Zeit, Statistik, Hypnose, Netzwerk, Machine Learning -- **Objektorientierung**: Sessions (Klassen), Methoden, Konstruktoren -- **Funktionen & Kontrollstrukturen**: if, while, loop, suggestion, imperative suggestion -- **Erweiterte Features**: Pattern Matching, Time Dilation, Memory Enhancement, Creativity Boost -- **CLI mit 18 Befehlen**: run, compile, analyze, web, api, deploy, monitor, test, docs, benchmark, profile, lint, optimize, ... -- **WASM-Codegenerator**: Kompilierung zu WebAssembly (WAT) -- **Self-contained Binaries**: Für Windows (winget) & Linux (APT) -- **Automatisierte Tests & Doku**: Umfangreiche Testprogramme, Docusaurus-Dokumentation +- 🦀 **Reine Rust-Codebasis** – schneller Build, keine .NET-Abhängigkeiten mehr +- 🧠 **Vollständige Toolchain** – Lexer, Parser, Type Checker, Interpreter und WASM-Codegen +- 🧰 **110+ Builtins** – Mathe, Strings, Arrays, Hypnose, Files, Zeit, System, Statistik, Hashing, Validation +- 🖥️ **CLI-Workflow** – `run`, `lex`, `parse`, `check`, `compile-wasm`, `builtins`, `version` +- ✅ **Umfangreiche Tests** – 48 Tests über alle Crates (Lexer, Runtime, Compiler, CLI) +- 📚 **Dokumentation** – Docusaurus im Ordner `HypnoScript.Dokumentation` +- 🚀 **Performance** – Zero-cost abstractions, kein Garbage Collector, nativer Code --- -## 🏗️ Architektur +## 🏗️ Workspace-Architektur -- **HypnoScript.Core**: Typen, Symboltabellen -- **HypnoScript.LexerParser**: Lexer, Parser, AST -- **HypnoScript.Compiler**: TypeChecker, Interpreter, WASM-Codegen -- **HypnoScript.Runtime**: Builtins, Systemfunktionen -- **HypnoScript.CLI**: Kommandozeilen-Interface -- **HypnoScript.Dokumentation**: Docusaurus-Doku +```text +hyp-runtime/ +├── Cargo.toml # Workspace-Konfiguration +├── hypnoscript-core/ # Typ-System & Symbole (100%) +├── hypnoscript-lexer-parser/ # Tokens, Lexer, AST, Parser (100%) +├── hypnoscript-compiler/ # Type Checker, Interpreter, WASM Codegen (100%) +├── hypnoscript-runtime/ # 110+ Builtin-Funktionen (75%) +└── hypnoscript-cli/ # Kommandozeileninterface (100%) +``` -**Beispielprogramme:** im Ordner `examples/` (empfohlen) oder als `test_*.hyp` in der Wurzel +Zur Dokumentation steht weiterhin `HypnoScript.Dokumentation/` (Docusaurus) bereit. --- -## 🛠️ Installation & Quick Start +## ⚙️ Installation & Quick Start ### Voraussetzungen -- .NET 8.0 SDK oder höher (siehe [Installationsanleitung](HypnoScript.Dokumentation/docs/getting-started/installation.md)) +- Rust 1.76+ (empfohlen) inkl. `cargo` -### Installation (Repository) +### Projekt klonen & bauen ```bash -git clone +git clone https://github.com/Kink-Development-Group/hyp-runtime.git cd hyp-runtime -dotnet build +cargo build --all --release ``` -### Quick Start +### Programm ausführen ```bash -dotnet run --project HypnoScript.CLI -- run test_enterprise_v3.hyp +./target/release/hypnoscript-cli run program.hyp ``` -### Windows (winget) +Oder während der Entwicklung: -```powershell -winget install HypnoScript.HypnoScript +```bash +cargo run -p hypnoscript-cli -- run test_simple.hyp ``` -### Linux (APT) +### Beispielprogramm -```bash -sudo apt update -sudo apt install hypnoscript +```hypnoscript +Focus { + entrance { + observe "Welcome to HypnoScript Rust Edition!"; + } + + induce x: number = 42; + induce message: string = "Hello Trance"; + + observe message; + observe x; + + if (x > 40) deepFocus { + observe "X is greater than 40"; + } +} Relax ``` -Weitere Details: [Installationsanleitung](HypnoScript.Dokumentation/docs/getting-started/installation.md) +### CLI-Befehle im Detail + +```bash +# Programm ausführen +hypnoscript-cli run program.hyp + +# Datei tokenisieren (Token-Stream anzeigen) +hypnoscript-cli lex program.hyp + +# AST anzeigen +hypnoscript-cli parse program.hyp + +# Typprüfung durchführen +hypnoscript-cli check program.hyp + +# Zu WebAssembly kompilieren +hypnoscript-cli compile-wasm program.hyp --output program.wat + +# Liste der Builtin-Funktionen +hypnoscript-cli builtins + +# Version anzeigen +hypnoscript-cli version +``` --- -## 📝 CLI-Überblick (Details: [CLI_README.md](CLI_README.md)) +## 🧪 Tests & Qualitätssicherung + +Alle Tests ausführen: ```bash -# Programm ausführen -dotnet run -- run [--debug] [--verbose] -# Zu WASM kompilieren -dotnet run -- compile -# Statische Analyse -dotnet run -- analyze -# Web/API/Deploy/Monitor -dotnet run -- web -# Tests -dotnet run -- test -# Dokumentation -dotnet run -- docs -# Hilfe -dotnet run -- help +cargo test --all ``` -**Alle Befehle und Optionen:** Siehe [CLI_README.md](CLI_README.md) +**_Ergebnis: Alle 48 Tests erfolgreich ✅_** + +Alle Crates besitzen Unit-Tests – Lexer, Parser, Runtime-Builtins, Type Checker, Interpreter und WASM Codegen. + +### Code-Qualität + +```bash +# Formatierung prüfen +cargo fmt --all -- --check + +# Linting mit Clippy +cargo clippy --all +``` --- -## 📚 Beispiele +## 📦 Builtin-Funktionen (110+) -### Grundlegendes HypnoScript-Programm +### Mathematik (20+) -```hypnoscript -Focus { - entrance { - observe "Willkommen in HypnoScript!"; - } - induce greeting: string = "Hello Trance!"; - observe greeting; - if (true) deepFocus { - observe "You are feeling very relaxed..."; +`Sin`, `Cos`, `Tan`, `Sqrt`, `Pow`, `Log`, `Abs`, `Floor`, `Ceil`, `Round`, `Min`, `Max`, `Factorial`, `Gcd`, `Lcm`, `IsPrime`, `Fibonacci`, `Clamp` + +### Strings (15+) + +`ToUpper`, `ToLower`, `Capitalize`, `TitleCase`, `IndexOf`, `Replace`, `Reverse`, `Split`, `Substring`, `Trim`, `Repeat`, `PadLeft`, `PadRight`, `StartsWith`, `EndsWith`, `Contains`, `Length`, `IsWhitespace` + +### Arrays (15+) + +`ArrayLength`, `ArraySum`, `ArrayAverage`, `ArrayMin`, `ArrayMax`, `ArraySort`, `ArrayReverse`, `ArrayDistinct`, `ArrayFirst`, `ArrayLast`, `ArrayTake`, `ArraySkip`, `ArraySlice`, `ArrayJoin`, `ArrayCount`, `ArrayIndexOf`, `ArrayContains`, `ArrayIsEmpty`, `ArrayGet` + +### Zeit/Datum (15) + +`GetCurrentTime`, `GetCurrentDate`, `GetCurrentDateTime`, `FormatDateTime`, `GetYear`, `GetMonth`, `GetDay`, `GetHour`, `GetMinute`, `GetSecond`, `GetDayOfWeek`, `GetDayOfYear`, `IsLeapYear`, `GetDaysInMonth`, `CurrentDate`, `DaysInMonth` + +### Validierung (10) + +`IsValidEmail`, `IsValidUrl`, `IsValidPhoneNumber`, `IsAlphanumeric`, `IsAlphabetic`, `IsNumeric`, `IsLowercase`, `IsUppercase`, `IsInRange`, `MatchesPattern` + +### Datei-I/O (14) + +`ReadFile`, `WriteFile`, `AppendFile`, `FileExists`, `IsFile`, `IsDirectory`, `DeleteFile`, `CreateDirectory`, `ListDirectory`, `GetFileSize`, `CopyFile`, `RenameFile`, `GetFileExtension`, `GetFileName` + +### Statistik (9) + +`CalculateMean`, `CalculateMedian`, `CalculateMode`, `CalculateStandardDeviation`, `CalculateVariance`, `CalculateRange`, `CalculatePercentile`, `CalculateCorrelation`, `LinearRegression`, `Mean`, `Variance` + +### Hashing/Utilities (10) + +`HashString`, `HashNumber`, `AreAnagrams`, `IsPalindrome`, `CountOccurrences`, `RemoveDuplicates`, `UniqueCharacters`, `ReverseWords`, `TitleCase`, `SimpleRandom` + +### System (12) + +`GetOperatingSystem`, `GetArchitecture`, `GetCpuCount`, `GetHostname`, `GetCurrentDirectory`, `GetHomeDirectory`, `GetTempDirectory`, `GetEnvVar`, `SetEnvVar`, `GetUsername`, `GetArgs`, `Exit` + +### Hypnose/Core (6) + +`Observe`, `Drift`, `DeepTrance`, `HypnoticCountdown`, `TranceInduction`, `HypnoticVisualization` + +### Konvertierungen (4) + +`ToInt`, `ToDouble`, `ToString`, `ToBoolean` + +Eine vollständige Liste liefert `hypnoscript-cli builtins` sowie die Dokumentation im Docusaurus. + +--- + +## 📊 Performance-Vorteile + +Rust bietet mehrere Vorteile gegenüber C#: + +1. **Zero-cost Abstractions**: Compile-time Optimierungen ohne Runtime-Overhead +2. **Kein Garbage Collector**: Deterministisches Speichermanagement +3. **Speichersicherheit**: Compile-time Verhinderung häufiger Bugs +4. **Kleinere Binaries**: 5-10MB vs. 60+MB für C# mit Runtime +5. **Bessere Parallelisierung**: Sicherer gleichzeitiger Zugriff via Ownership-Modell +6. **Schnellere Ausführung**: Nativer Code mit LLVM-Optimierungen + +--- + +## 🔧 Entwicklung + +### Neue Builtins hinzufügen + +1. Funktion zum passenden Modul in `hypnoscript-runtime/src/` hinzufügen +2. Tests in derselben Datei hinzufügen +3. Builtins-Liste im CLI aktualisieren +4. Aus `lib.rs` exportieren + +Beispiel: + +```rust +// In math_builtins.rs +pub fn new_function(x: f64) -> f64 { + // Implementierung +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_new_function() { + assert_eq!(MathBuiltins::new_function(5.0), expected_result); } -} Relax +} ``` -### Erweiterte Features, OOP, Machine Learning, Netzwerk +### Code-Style -Siehe [Doku-Beispiele](HypnoScript.Dokumentation/docs/examples/basic-examples.md) und [test_*.hyp] +- Rust-Standard-Style befolgen (nutze `cargo fmt`) +- Clippy für Linting ausführen: `cargo clippy` +- Funktionen fokussiert und gut dokumentiert halten +- Tests für neue Funktionalität schreiben --- -## 🔧 Builtin-Überblick +## 📝 Migrationsstatus -- **Mathematik**: Sin, Cos, Tan, Sqrt, Pow, Log, Random, Factorial, GCD, LCM, ... -- **Strings**: Length, ToUpper, ToLower, Trim, IndexOf, Replace, Reverse, Capitalize, ... -- **Arrays**: ArrayLength, ArrayGet, ArraySet, ArraySort, ArrayMap, ArrayReduce, ... -- **System**: GetCurrentDirectory, GetMachineName, GetUserName, ... -- **Zeit/Datum**: GetCurrentTime, FormatDateTime, IsLeapYear, ... -- **Statistik/ML**: CalculateMean, CalculateStandardDeviation, LinearRegression -- **Hypnose**: DeepTrance, HypnoticSuggestion, HypnoticPatternMatching, ... -- **Netzwerk**: HttpGet, HttpPost -- **Datenbank**: CreateRecord, GetRecordValue, ... -- **Validierung**: IsValidEmail, IsValidUrl, ... +**_Gesamt: ~95% Komplett_** -**Vollständige Liste:** [Doku Builtins](HypnoScript.Dokumentation/docs/builtins/overview.md) +- ✅ Core-Typ-System (100%) +- ✅ Symbol-Tabelle (100%) +- ✅ Lexer (100%) +- ✅ Parser (100%) +- ✅ Type Checker (100%) +- ✅ Interpreter (100%) +- ✅ WASM Codegen (100%) +- ✅ Runtime-Builtins (75% - 110+ von 150+) +- ✅ CLI-Framework (100%) +- ✅ CI/CD-Pipelines (100%) --- -## 🏗️ Build & Distribution +## 🎯 Roadmap -- **Windows:** `dotnet publish HypnoScript.CLI -c Release -r win-x64 --self-contained true -p:PublishSingleFile=true -o ./publish/win` -- **Linux:** `dotnet publish HypnoScript.CLI -c Release -r linux-x64 --self-contained true -p:PublishSingleFile=true -o ./publish/linux` -- **Paketierung:** Siehe [scripts/README.md](scripts/README.md) +### Abgeschlossen ✅ + +- [x] Lexer-Implementierung +- [x] Parser-Implementierung +- [x] Type Checker-Implementierung +- [x] Interpreter-Implementierung +- [x] WASM Code Generator-Implementierung +- [x] 110+ Builtin-Funktionen +- [x] Vollständige Programmausführung +- [x] CLI-Integration (7 Befehle) +- [x] CI/CD-Pipelines +- [x] Umfassende Tests (48 Tests) + +### Optionale Erweiterungen 🔄 + +- [ ] Zusätzliche 40 spezialisierte Builtins (Netzwerk, ML) +- [ ] Session/OOP-Features +- [ ] Erweiterte Fehlerbehandlung +- [ ] Performance-Benchmarking vs. C# +- [ ] Optimierungs-Passes + +--- + +## 🐛 Bekannte Einschränkungen + +- Einige fortgeschrittene C#-Builtins noch ausstehend (Netzwerk-, ML-Features - optional) +- Session/OOP-Features sind optionale Erweiterungen --- -## 💡 Best Practices & Roadmap +## 🧭 Migration & Projektstatus + +- ✅ C#-Codebasis entfernt (alle ehemaligen `.csproj`-Projekte wurden gelöscht) +- ✅ Rust-Workspace produktiv einsetzbar +- ✅ Kompletter Port der Kernfunktionalität +- ✅ Alle 48 Tests erfolgreich +- 🔄 Optionale Erweiterungen (z. B. Netzwerk-/ML-Builtins) sind als Roadmap möglich -- **Projektstruktur:** Trenne Quellcode, Tests, Skripte, Doku, Beispiele -- **Automatisierung:** Nutze CI/CD für Build, Test, Release, Doku-Deployment -- **Erweiterbarkeit:** CLI und Builtins sind modular – eigene Erweiterungen möglich -- **Doku:** Halte Readmes und Builtin-Listen synchron (ggf. automatisiert) -- **Roadmap:** - 1. Web-Interface - 2. Package Manager - 3. IDE-Integration - 4. Cloud-Deployment - 5. Erweiterte ML/AI-Features +Details zur Migration: siehe `IMPLEMENTATION_SUMMARY.md`. --- -## 🛠️ Troubleshooting & Support +## 🔗 Links & Ressourcen -- **.NET nicht gefunden:** Prüfe mit `dotnet --version` (siehe [Installationsanleitung](HypnoScript.Dokumentation/docs/getting-started/installation.md)) -- **Build-Fehler:** `dotnet restore`, `dotnet clean`, `dotnet build` -- **Pfade:** Achte auf plattformübergreifende Pfade in Skripten und Doku -- **Support:** - - [GitHub Issues](https://github.com/Kink-Development-Group/hyp-runtime/issues) - - [Discussions](https://github.com/Kink-Development-Group/hyp-runtime/discussions) - - [Doku Troubleshooting](HypnoScript.Dokumentation/docs/development/debugging.md) +- 📘 [Rust Book](https://doc.rust-lang.org/book/) +- 📦 [Cargo-Dokumentation](https://doc.rust-lang.org/cargo/) +- 🧾 Projekt-Doku: `HypnoScript.Dokumentation/` +- 🐞 Issues & Diskussionen: --- -## 🔗 Weiterführende Links +## 🤝 Contributing -- **Doku:** [HypnoScript.Dokumentation/README.md](HypnoScript.Dokumentation/README.md) -- **Online-Doku:** -- **CLI-Details:** [CLI_README.md](CLI_README.md) -- **Build/Paketierung:** [scripts/README.md](scripts/README.md) -- **Lizenz:** MIT ([LICENSE](LICENSE)) +Bei Beiträgen zur Rust-Implementierung: + +1. API-Kompatibilität mit der C#-Version wo möglich beibehalten +2. DRY-Prinzipien befolgen (Don't Repeat Yourself) +3. Umfassende Tests schreiben +4. Öffentliche APIs dokumentieren +5. `cargo fmt` und `cargo clippy` vor dem Commit ausführen --- -## Automatisierte Dokumentation, CI/CD und Testabdeckung +## 📄 License -- Die Builtin-Dokumentation wird automatisch aus dem Code generiert und mit der Doku synchronisiert. -- Die CI/CD-Pipeline (GitHub Actions) baut, testet und released automatisch für Windows und Linux. -- Testabdeckung und Monitoring werden kontinuierlich ausgebaut. -- Fehlerbehandlung und Logging folgen Best Practices für Zuverlässigkeit und Wartbarkeit. +MIT License (gleiche wie das Original-Projekt) --- -**Bereit für die hypnotische Programmierung?** +**_Die Rust-Runtime ist production-ready für HypnoScript-Kernprogrammierung! 🚀_** + +**Viel Spaß beim hypnotischen Programmieren mit Rust!** diff --git a/deny.toml b/deny.toml new file mode 100644 index 0000000..9fe559e --- /dev/null +++ b/deny.toml @@ -0,0 +1,245 @@ +# This template contains all of the possible sections and their default values + +# Note that all fields that take a lint level have these possible values: +# * deny - An error will be produced and the check will fail +# * warn - A warning will be produced, but the check will not fail +# * allow - No warning or error will be produced, though in some cases a note +# will be + +# The values provided in this template are the default values that will be used +# when any section or field is not specified in your own configuration + +# Root options + +# The graph table configures how the dependency graph is constructed and thus +# which crates the checks are performed against +[graph] +# If 1 or more target triples (and optionally, target_features) are specified, +# only the specified targets will be checked when running `cargo deny check`. +# This means, if a particular package is only ever used as a target specific +# dependency, such as, for example, the `nix` crate only being used via the +# `target_family = "unix"` configuration, that only having windows targets in +# this list would mean the nix crate, as well as any of its exclusive +# dependencies not shared by any other crates, would be ignored, as the target +# list here is effectively saying which targets you are building for. +targets = [ + # The triple can be any string, but only the target triples built in to + # rustc (as of 1.40) can be checked against actual config expressions + #"x86_64-unknown-linux-musl", + # You can also specify which target_features you promise are enabled for a + # particular target. target_features are currently not validated against + # the actual valid features supported by the target architecture. + #{ triple = "wasm32-unknown-unknown", features = ["atomics"] }, +] +# When creating the dependency graph used as the source of truth when checks are +# executed, this field can be used to prune crates from the graph, removing them +# from the view of cargo-deny. This is an extremely heavy hammer, as if a crate +# is pruned from the graph, all of its dependencies will also be pruned unless +# they are connected to another crate in the graph that hasn't been pruned, +# so it should be used with care. The identifiers are [Package ID Specifications] +# (https://doc.rust-lang.org/cargo/reference/pkgid-spec.html) +#exclude = [] +# If true, metadata will be collected with `--all-features`. Note that this can't +# be toggled off if true, if you want to conditionally enable `--all-features` it +# is recommended to pass `--all-features` on the cmd line instead +all-features = false +# If true, metadata will be collected with `--no-default-features`. The same +# caveat with `all-features` applies +no-default-features = false +# If set, these feature will be enabled when collecting metadata. If `--features` +# is specified on the cmd line they will take precedence over this option. +#features = [] + +# The output table provides options for how/if diagnostics are outputted +[output] +# When outputting inclusion graphs in diagnostics that include features, this +# option can be used to specify the depth at which feature edges will be added. +# This option is included since the graphs can be quite large and the addition +# of features from the crate(s) to all of the graph roots can be far too verbose. +# This option can be overridden via `--feature-depth` on the cmd line +feature-depth = 1 + +# This section is considered when running `cargo deny check advisories` +# More documentation for the advisories section can be found here: +# https://embarkstudios.github.io/cargo-deny/checks/advisories/cfg.html +[advisories] +# The path where the advisory databases are cloned/fetched into +#db-path = "$CARGO_HOME/advisory-dbs" +# The url(s) of the advisory databases to use +#db-urls = ["https://github.com/rustsec/advisory-db"] +# A list of advisory IDs to ignore. Note that ignored advisories will still +# output a note when they are encountered. +ignore = [ + #"RUSTSEC-0000-0000", + #{ id = "RUSTSEC-0000-0000", reason = "you can specify a reason the advisory is ignored" }, + #"a-crate-that-is-yanked@0.1.1", # you can also ignore yanked crate versions if you wish + #{ crate = "a-crate-that-is-yanked@0.1.1", reason = "you can specify why you are ignoring the yanked crate" }, +] +# If this is true, then cargo deny will use the git executable to fetch advisory database. +# If this is false, then it uses a built-in git library. +# Setting this to true can be helpful if you have special authentication requirements that cargo-deny does not support. +# See Git Authentication for more information about setting up git authentication. +#git-fetch-with-cli = true + +# This section is considered when running `cargo deny check licenses` +# More documentation for the licenses section can be found here: +# https://embarkstudios.github.io/cargo-deny/checks/licenses/cfg.html +[licenses] +# List of explicitly allowed licenses +# See https://spdx.org/licenses/ for list of possible licenses +# [possible values: any SPDX 3.11 short identifier (+ optional exception)]. +allow = [ + "Apache-2.0", + "Apache-2.0 WITH LLVM-exception", + "BSD-2-Clause", + "BSD-3-Clause", + "BSL-1.0", + "CC0-1.0", + "ISC", + "MIT", + "Unicode-3.0", + "Unicode-DFS-2016", + "Unlicense", + "Zlib", +] +# The confidence threshold for detecting a license from license text. +# The higher the value, the more closely the license text must be to the +# canonical license text of a valid SPDX license file. +# [possible values: any between 0.0 and 1.0]. +confidence-threshold = 0.8 +# Allow 1 or more licenses on a per-crate basis, so that particular licenses +# aren't accepted for every possible crate as with the normal allow list +exceptions = [ + # Each entry is the crate and version constraint, and its specific allow + # list + #{ allow = ["Zlib"], crate = "adler32" }, + { crate = "android_system_properties", allow = ["Apache-2.0", "MIT"] }, +] + +# Some crates don't have (easily) machine readable licensing information, +# adding a clarification entry for it allows you to manually specify the +# licensing information +#[[licenses.clarify]] +# The package spec the clarification applies to +#crate = "ring" +# The SPDX expression for the license requirements of the crate +#expression = "MIT AND ISC AND OpenSSL" +# One or more files in the crate's source used as the "source of truth" for +# the license expression. If the contents match, the clarification will be used +# when running the license check, otherwise the clarification will be ignored +# and the crate will be checked normally, which may produce warnings or errors +# depending on the rest of your configuration +#license-files = [ +# Each entry is a crate relative path, and the (opaque) hash of its contents +#{ path = "LICENSE", hash = 0xbd0eed23 } +#] + +[licenses.private] +# If true, ignores workspace crates that aren't published, or are only +# published to private registries. +# To see how to mark a crate as unpublished (to the official registry), +# visit https://doc.rust-lang.org/cargo/reference/manifest.html#the-publish-field. +ignore = false +# One or more private registries that you might publish crates to, if a crate +# is only published to private registries, and ignore is true, the crate will +# not have its license(s) checked +registries = [ + #"https://sekretz.com/registry +] + +# This section is considered when running `cargo deny check bans`. +# More documentation about the 'bans' section can be found here: +# https://embarkstudios.github.io/cargo-deny/checks/bans/cfg.html +[bans] +# Lint level for when multiple versions of the same crate are detected +multiple-versions = "warn" +# Lint level for when a crate version requirement is `*` +wildcards = "allow" +# The graph highlighting used when creating dotgraphs for crates +# with multiple versions +# * lowest-version - The path to the lowest versioned duplicate is highlighted +# * simplest-path - The path to the version with the fewest edges is highlighted +# * all - Both lowest-version and simplest-path are used +highlight = "all" +# The default lint level for `default` features for crates that are members of +# the workspace that is being checked. This can be overridden by allowing/denying +# `default` on a crate-by-crate basis if desired. +workspace-default-features = "allow" +# The default lint level for `default` features for external crates that are not +# members of the workspace. This can be overridden by allowing/denying `default` +# on a crate-by-crate basis if desired. +external-default-features = "allow" +# List of crates that are allowed. Use with care! +allow = [ + #"ansi_term@0.11.0", + #{ crate = "ansi_term@0.11.0", reason = "you can specify a reason it is allowed" }, +] +# List of crates to deny +deny = [ + #"ansi_term@0.11.0", + #{ crate = "ansi_term@0.11.0", reason = "you can specify a reason it is banned" }, + # Wrapper crates can optionally be specified to allow the crate when it + # is a direct dependency of the otherwise banned crate + #{ crate = "ansi_term@0.11.0", wrappers = ["this-crate-directly-depends-on-ansi_term"] }, +] + +# List of features to allow/deny +# Each entry the name of a crate and a version range. If version is +# not specified, all versions will be matched. +#[[bans.features]] +#crate = "reqwest" +# Features to not allow +#deny = ["json"] +# Features to allow +#allow = [ +# "rustls", +# "__rustls", +# "__tls", +# "hyper-rustls", +# "rustls", +# "rustls-pemfile", +# "rustls-tls-webpki-roots", +# "tokio-rustls", +# "webpki-roots", +#] +# If true, the allowed features must exactly match the enabled feature set. If +# this is set there is no point setting `deny` +#exact = true + +# Certain crates/versions that will be skipped when doing duplicate detection. +skip = [ + #"ansi_term@0.11.0", + #{ crate = "ansi_term@0.11.0", reason = "you can specify a reason why it can't be updated/removed" }, +] +# Similarly to `skip` allows you to skip certain crates during duplicate +# detection. Unlike skip, it also includes the entire tree of transitive +# dependencies starting at the specified crate, up to a certain depth, which is +# by default infinite. +skip-tree = [ + #"ansi_term@0.11.0", # will be skipped along with _all_ of its direct and transitive dependencies + #{ crate = "ansi_term@0.11.0", depth = 20 }, +] + +# This section is considered when running `cargo deny check sources`. +# More documentation about the 'sources' section can be found here: +# https://embarkstudios.github.io/cargo-deny/checks/sources/cfg.html +[sources] +# Lint level for what to happen when a crate from a crate registry that is not +# in the allow list is encountered +unknown-registry = "warn" +# Lint level for what to happen when a crate from a git repository that is not +# in the allow list is encountered +unknown-git = "warn" +# List of URLs for allowed crate registries. Defaults to the crates.io index +# if not specified. If it is specified but empty, no registries are allowed. +allow-registry = ["https://github.com/rust-lang/crates.io-index"] +# List of URLs for allowed Git repositories +allow-git = [] + +[sources.allow-org] +# github.com organizations to allow git sources for +github = [] +# gitlab.com organizations to allow git sources for +gitlab = [] +# bitbucket.org organizations to allow git sources for +bitbucket = [] diff --git a/hypnoscript-cli/Cargo.toml b/hypnoscript-cli/Cargo.toml new file mode 100644 index 0000000..043f555 --- /dev/null +++ b/hypnoscript-cli/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "hypnoscript-cli" +version.workspace = true +edition.workspace = true +authors.workspace = true +license.workspace = true +repository.workspace = true + +[dependencies] +hypnoscript-core = { path = "../hypnoscript-core" } +hypnoscript-lexer-parser = { path = "../hypnoscript-lexer-parser" } +hypnoscript-compiler = { path = "../hypnoscript-compiler" } +hypnoscript-runtime = { path = "../hypnoscript-runtime" } +anyhow = { workspace = true } +clap = { version = "4.5", features = ["derive"] } diff --git a/hypnoscript-cli/src/main.rs b/hypnoscript-cli/src/main.rs new file mode 100644 index 0000000..99f5beb --- /dev/null +++ b/hypnoscript-cli/src/main.rs @@ -0,0 +1,243 @@ +use anyhow::Result; +use clap::{Parser, Subcommand}; +use hypnoscript_compiler::{Interpreter, TypeChecker, WasmCodeGenerator}; +use hypnoscript_lexer_parser::{Lexer, Parser as HypnoParser}; +use std::fs; + +fn into_anyhow(error: E) -> anyhow::Error { + anyhow::Error::msg(error.to_string()) +} + +#[derive(Parser)] +#[command(name = "hypnoscript")] +#[command(about = "HypnoScript - The Hypnotic Programming Language (Rust Edition)", long_about = None)] +struct Cli { + #[command(subcommand)] + command: Commands, +} + +#[derive(Subcommand)] +enum Commands { + /// Run a HypnoScript file + Run { + /// Path to the .hyp file + file: String, + + /// Enable debug mode + #[arg(short, long)] + debug: bool, + + /// Enable verbose output + #[arg(short, long)] + verbose: bool, + }, + + /// Lex a HypnoScript file (tokenize) + Lex { + /// Path to the .hyp file + file: String, + }, + + /// Parse a HypnoScript file (show AST) + Parse { + /// Path to the .hyp file + file: String, + }, + + /// Type check a HypnoScript file + Check { + /// Path to the .hyp file + file: String, + }, + + /// Compile to WASM + CompileWasm { + /// Path to the .hyp file + input: String, + + /// Output WASM file + #[arg(short, long)] + output: Option, + }, + + /// Show version information + Version, + + /// Show builtin functions + Builtins, +} + +fn main() -> Result<()> { + let cli = Cli::parse(); + + match cli.command { + Commands::Run { + file, + debug, + verbose, + } => { + if verbose { + println!("Running file: {}", file); + } + + let source = fs::read_to_string(&file)?; + + if debug { + println!("Source code:"); + println!("{}", source); + println!("\n--- Lexing ---"); + } + + // Lex + let mut lexer = Lexer::new(&source); + let tokens = lexer.lex().map_err(into_anyhow)?; + + if debug { + println!("Tokens: {}", tokens.len()); + } + + // Parse + let mut parser = HypnoParser::new(tokens); + let ast = parser.parse_program().map_err(into_anyhow)?; + + if debug { + println!("\n--- Type Checking ---"); + } + + // Type check + let mut type_checker = TypeChecker::new(); + let errors = type_checker.check_program(&ast); + if !errors.is_empty() { + eprintln!("Type errors:"); + for error in errors { + eprintln!(" - {}", error); + } + if !debug { + eprintln!("\nContinuing execution despite type errors..."); + } + } + + if debug { + println!("\n--- Executing ---"); + } + + // Execute + let mut interpreter = Interpreter::new(); + interpreter.execute_program(ast).map_err(into_anyhow)?; + + if verbose { + println!("\n✅ Program executed successfully!"); + } + } + + Commands::Lex { file } => { + let source = fs::read_to_string(&file)?; + let mut lexer = Lexer::new(&source); + let tokens = lexer.lex().map_err(into_anyhow)?; + + println!("=== Tokens ==="); + for (i, token) in tokens.iter().enumerate() { + println!("{:4}: {:?}", i, token); + } + println!("\nTotal tokens: {}", tokens.len()); + } + + Commands::Parse { file } => { + let source = fs::read_to_string(&file)?; + let mut lexer = Lexer::new(&source); + let tokens = lexer.lex().map_err(into_anyhow)?; + let mut parser = HypnoParser::new(tokens); + let ast = parser.parse_program().map_err(into_anyhow)?; + + println!("=== AST ==="); + println!("{:#?}", ast); + } + + Commands::Check { file } => { + let source = fs::read_to_string(&file)?; + let mut lexer = Lexer::new(&source); + let tokens = lexer.lex().map_err(into_anyhow)?; + let mut parser = HypnoParser::new(tokens); + let ast = parser.parse_program().map_err(into_anyhow)?; + + let mut type_checker = TypeChecker::new(); + let errors = type_checker.check_program(&ast); + + if errors.is_empty() { + println!("✅ No type errors found!"); + } else { + println!("❌ Type errors found:"); + for error in errors { + println!(" - {}", error); + } + } + } + + Commands::CompileWasm { input, output } => { + let source = fs::read_to_string(&input)?; + let mut lexer = Lexer::new(&source); + let tokens = lexer.lex().map_err(into_anyhow)?; + let mut parser = HypnoParser::new(tokens); + let ast = parser.parse_program().map_err(into_anyhow)?; + + let mut generator = WasmCodeGenerator::new(); + let wasm_code = generator.generate(&ast); + + let output_file = output.unwrap_or_else(|| input.replace(".hyp", ".wat")); + + fs::write(&output_file, wasm_code)?; + println!("✅ WASM code written to: {}", output_file); + } + + Commands::Version => { + println!("HypnoScript v1.0.0 (Rust Edition)"); + println!("The Hypnotic Programming Language"); + println!(); + println!("Migrated from C# to Rust for improved performance"); + println!(); + println!("Features:"); + println!(" - Full parser and interpreter"); + println!(" - Type checker"); + println!(" - WASM code generation"); + println!(" - 110+ builtin functions"); + } + + Commands::Builtins => { + println!("=== HypnoScript Builtin Functions ===\n"); + + println!("📊 Math Builtins:"); + println!(" - Sin, Cos, Tan, Sqrt, Pow, Log, Log10"); + println!(" - Abs, Floor, Ceil, Round, Min, Max"); + println!(" - Factorial, Gcd, Lcm, IsPrime, Fibonacci"); + println!(" - Clamp"); + + println!("\n📝 String Builtins:"); + println!(" - Length, ToUpper, ToLower, Trim"); + println!(" - IndexOf, Replace, Reverse, Capitalize"); + println!(" - StartsWith, EndsWith, Contains"); + println!(" - Split, Substring, Repeat"); + println!(" - PadLeft, PadRight"); + + println!("\n📦 Array Builtins:"); + println!(" - Length, IsEmpty, Get, IndexOf, Contains"); + println!(" - Reverse, Sum, Average, Min, Max, Sort"); + println!(" - First, Last, Take, Skip, Slice"); + println!(" - Join, Count, Distinct"); + + println!("\n✨ Hypnotic Builtins:"); + println!(" - observe (output)"); + println!(" - drift (sleep)"); + println!(" - DeepTrance"); + println!(" - HypnoticCountdown"); + println!(" - TranceInduction"); + println!(" - HypnoticVisualization"); + + println!("\n🔄 Conversion Functions:"); + println!(" - ToInt, ToDouble, ToString, ToBoolean"); + + println!("\nTotal: 50+ builtin functions implemented"); + } + } + + Ok(()) +} diff --git a/hypnoscript-compiler/Cargo.toml b/hypnoscript-compiler/Cargo.toml new file mode 100644 index 0000000..08d1a6a --- /dev/null +++ b/hypnoscript-compiler/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "hypnoscript-compiler" +version.workspace = true +edition.workspace = true +authors.workspace = true +license.workspace = true +repository.workspace = true + +[dependencies] +hypnoscript-core = { path = "../hypnoscript-core" } +hypnoscript-lexer-parser = { path = "../hypnoscript-lexer-parser" } +hypnoscript-runtime = { path = "../hypnoscript-runtime" } +anyhow = { workspace = true } +thiserror = { workspace = true } diff --git a/hypnoscript-compiler/src/interpreter.rs b/hypnoscript-compiler/src/interpreter.rs new file mode 100644 index 0000000..9e2ff82 --- /dev/null +++ b/hypnoscript-compiler/src/interpreter.rs @@ -0,0 +1,2390 @@ +use hypnoscript_lexer_parser::ast::{ + AstNode, SessionField, SessionMember, SessionMethod, SessionVisibility, +}; +use hypnoscript_runtime::{ + ArrayBuiltins, CoreBuiltins, FileBuiltins, HashingBuiltins, MathBuiltins, StatisticsBuiltins, + StringBuiltins, SystemBuiltins, TimeBuiltins, ValidationBuiltins, +}; +use std::cell::RefCell; +use std::collections::HashMap; +use std::rc::Rc; +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum InterpreterError { + #[error("Runtime error: {0}")] + Runtime(String), + #[error("Break statement outside of loop")] + BreakOutsideLoop, + #[error("Continue statement outside of loop")] + ContinueOutsideLoop, + #[error("Return from function: {0:?}")] + Return(Value), + #[error("Variable '{0}' not found")] + UndefinedVariable(String), + #[error("Type error: {0}")] + TypeError(String), +} + +/// Provide a simple locale-aware message while we prepare full i18n plumbing. +fn localized(en: &str, de: &str) -> String { + format!("{} (DE: {})", en, de) +} + +/// Represents a callable suggestion within the interpreter. +#[derive(Debug, Clone)] +pub struct FunctionValue { + name: String, + parameters: Vec, + body: Vec, + this_binding: Option>>, + session_name: Option, + is_static: bool, + is_constructor: bool, +} + +impl FunctionValue { + fn new_global(name: String, parameters: Vec, body: Vec) -> Self { + Self { + name, + parameters, + body, + this_binding: None, + session_name: None, + is_static: false, + is_constructor: false, + } + } + + fn new_session_member( + session_name: String, + method: &SessionMethodDefinition, + this_binding: Option>>, + ) -> Self { + Self { + name: format!("{}::{}", session_name, method.name), + parameters: method.parameters.clone(), + body: method.body.clone(), + this_binding, + session_name: Some(session_name), + is_static: method.is_static, + is_constructor: method.is_constructor, + } + } + + fn this_binding(&self) -> Option>> { + self.this_binding.as_ref().map(Rc::clone) + } + + fn session_name(&self) -> Option<&str> { + self.session_name.as_deref() + } +} + +impl PartialEq for FunctionValue { + fn eq(&self, other: &Self) -> bool { + self.name == other.name + && self.parameters == other.parameters + && self.body == other.body + && self.session_name == other.session_name + && self.is_static == other.is_static + && self.is_constructor == other.is_constructor + } +} + +impl Eq for FunctionValue {} + +/// Definition of a session field (instance scope). +#[derive(Debug, Clone)] +struct SessionFieldDefinition { + name: String, + #[allow(dead_code)] + type_annotation: Option, + visibility: SessionVisibility, + initializer: Option, +} + +/// Definition of a session method. +#[derive(Debug, Clone)] +struct SessionMethodDefinition { + name: String, + parameters: Vec, + body: Vec, + visibility: SessionVisibility, + is_static: bool, + is_constructor: bool, +} + +/// Runtime data for a static field, including its initializer AST. +#[derive(Debug, Clone)] +struct SessionStaticField { + definition: SessionFieldDefinition, + initializer: Option, + value: Value, +} + +/// Stores metadata and static members for a session (class-like construct). +#[derive(Debug)] +pub struct SessionDefinition { + name: String, + fields: HashMap, + field_order: Vec, + methods: HashMap, + static_methods: HashMap, + static_fields: RefCell>, + static_field_order: Vec, + constructor: Option, +} + +impl SessionDefinition { + fn new(name: String) -> Self { + Self { + name, + fields: HashMap::new(), + field_order: Vec::new(), + methods: HashMap::new(), + static_methods: HashMap::new(), + static_fields: RefCell::new(HashMap::new()), + static_field_order: Vec::new(), + constructor: None, + } + } + + fn name(&self) -> &str { + &self.name + } + + fn push_field(&mut self, field: SessionFieldDefinition) -> Result<(), InterpreterError> { + if self.fields.contains_key(&field.name) + || self.static_fields.borrow().contains_key(&field.name) + { + return Err(InterpreterError::Runtime(localized( + &format!( + "Duplicate session field '{}' in session '{}'", + field.name, self.name + ), + &format!("Doppeltes Feld '{}' in Session '{}'", field.name, self.name), + ))); + } + self.field_order.push(field.name.clone()); + self.fields.insert(field.name.clone(), field); + Ok(()) + } + + fn push_static_field( + &mut self, + field: SessionFieldDefinition, + initializer: Option, + ) -> Result<(), InterpreterError> { + if self.fields.contains_key(&field.name) + || self.static_fields.borrow().contains_key(&field.name) + { + return Err(InterpreterError::Runtime(localized( + &format!( + "Duplicate session field '{}' in session '{}'", + field.name, self.name + ), + &format!("Doppeltes Feld '{}' in Session '{}'", field.name, self.name), + ))); + } + self.static_field_order.push(field.name.clone()); + self.static_fields.borrow_mut().insert( + field.name.clone(), + SessionStaticField { + definition: field, + initializer, + value: Value::Null, + }, + ); + Ok(()) + } + + fn push_method(&mut self, method: SessionMethodDefinition) -> Result<(), InterpreterError> { + if method.is_constructor { + if self.constructor.is_some() { + return Err(InterpreterError::Runtime(localized( + &format!("Multiple constructors declared in session '{}'", self.name), + &format!( + "Mehrere Konstruktoren in Session '{}' deklariert", + self.name + ), + ))); + } + self.constructor = Some(method); + return Ok(()); + } + + if method.is_static { + if self.static_methods.contains_key(&method.name) { + return Err(InterpreterError::Runtime(localized( + &format!( + "Duplicate static method '{}' in session '{}'", + method.name, self.name + ), + &format!( + "Doppelte statische Methode '{}' in Session '{}'", + method.name, self.name + ), + ))); + } + self.static_methods.insert(method.name.clone(), method); + } else { + if self.methods.contains_key(&method.name) { + return Err(InterpreterError::Runtime(localized( + &format!( + "Duplicate method '{}' in session '{}'", + method.name, self.name + ), + &format!( + "Doppelte Methode '{}' in Session '{}'", + method.name, self.name + ), + ))); + } + self.methods.insert(method.name.clone(), method); + } + Ok(()) + } + + fn get_field_definition(&self, name: &str) -> Option<&SessionFieldDefinition> { + self.fields.get(name) + } + + fn get_method_definition(&self, name: &str) -> Option<&SessionMethodDefinition> { + self.methods.get(name) + } + + fn get_static_method_definition(&self, name: &str) -> Option<&SessionMethodDefinition> { + self.static_methods.get(name) + } + + fn get_static_field_snapshot(&self, name: &str) -> Option { + self.static_fields.borrow().get(name).cloned() + } + + fn set_static_field_value(&self, name: &str, value: Value) -> Result<(), InterpreterError> { + let mut fields = self.static_fields.borrow_mut(); + match fields.get_mut(name) { + Some(field) => { + field.value = value; + Ok(()) + } + None => Err(InterpreterError::Runtime(localized( + &format!( + "Static field '{}' not found on session '{}'", + name, self.name + ), + &format!( + "Statisches Feld '{}' nicht in Session '{}' gefunden", + name, self.name + ), + ))), + } + } + + fn take_static_field_initializer(&self, name: &str) -> Option { + self.static_fields + .borrow() + .get(name) + .and_then(|field| field.initializer.clone()) + } + + fn field_order(&self) -> &[String] { + &self.field_order + } + + fn static_field_order(&self) -> &[String] { + &self.static_field_order + } + + fn constructor(&self) -> Option<&SessionMethodDefinition> { + self.constructor.as_ref() + } +} + +/// Runtime representation of a session instance. +#[derive(Debug)] +pub struct SessionInstance { + definition: Rc, + field_values: HashMap, +} + +impl SessionInstance { + fn new(definition: Rc) -> Self { + let mut field_values = HashMap::new(); + for name in definition.field_order() { + field_values.insert(name.clone(), Value::Null); + } + Self { + definition, + field_values, + } + } + + fn definition(&self) -> Rc { + Rc::clone(&self.definition) + } + + fn definition_name(&self) -> &str { + self.definition.name() + } + + fn get_field(&self, name: &str) -> Option { + self.field_values.get(name).cloned() + } + + fn set_field(&mut self, name: &str, value: Value) { + self.field_values.insert(name.to_string(), value); + } +} + +#[derive(Debug, Clone)] +struct ExecutionContextFrame { + session_name: Option, +} + +/// Runtime value in HypnoScript +#[derive(Debug, Clone)] +pub enum Value { + Number(f64), + String(String), + Boolean(bool), + Array(Vec), + Function(FunctionValue), + Session(Rc), + Instance(Rc>), + Null, +} + +impl PartialEq for Value { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (Value::Number(a), Value::Number(b)) => (a - b).abs() < f64::EPSILON, + (Value::String(a), Value::String(b)) => a == b, + (Value::Boolean(a), Value::Boolean(b)) => a == b, + (Value::Null, Value::Null) => true, + (Value::Array(a), Value::Array(b)) => a == b, + (Value::Function(fa), Value::Function(fb)) => fa == fb, + (Value::Session(sa), Value::Session(sb)) => Rc::ptr_eq(sa, sb), + (Value::Instance(ia), Value::Instance(ib)) => Rc::ptr_eq(ia, ib), + _ => false, + } + } +} + +impl Eq for Value {} + +impl Value { + pub fn is_truthy(&self) -> bool { + match self { + Value::Boolean(b) => *b, + Value::Null => false, + Value::Number(n) => *n != 0.0, + Value::String(s) => !s.is_empty(), + Value::Array(a) => !a.is_empty(), + Value::Function(_) | Value::Session(_) | Value::Instance(_) => true, + } + } + + pub fn to_number(&self) -> Result { + match self { + Value::Number(n) => Ok(*n), + Value::String(s) => s.parse::().map_err(|_| { + InterpreterError::TypeError(format!("Cannot convert '{}' to number", s)) + }), + Value::Boolean(b) => Ok(if *b { 1.0 } else { 0.0 }), + _ => Err(InterpreterError::TypeError( + "Cannot convert to number".to_string(), + )), + } + } +} + +impl std::fmt::Display for Value { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Value::Number(n) => write!(f, "{}", n), + Value::String(s) => write!(f, "{}", s), + Value::Boolean(b) => write!(f, "{}", b), + Value::Null => write!(f, "null"), + Value::Array(arr) => { + let elements: Vec = arr.iter().map(|v| v.to_string()).collect(); + write!(f, "[{}]", elements.join(", ")) + } + Value::Function(func) => write!(f, "", func.name), + Value::Session(session) => write!(f, "", session.name()), + Value::Instance(instance) => { + let name = instance.borrow().definition_name().to_string(); + write!(f, "", name) + } + } + } +} + +pub struct Interpreter { + globals: HashMap, + locals: Vec>, + execution_context: Vec, +} + +impl Default for Interpreter { + fn default() -> Self { + Self::new() + } +} + +impl Interpreter { + pub fn new() -> Self { + Self { + globals: HashMap::new(), + locals: Vec::new(), + execution_context: Vec::new(), + } + } + + pub fn execute_program(&mut self, program: AstNode) -> Result<(), InterpreterError> { + if let AstNode::Program(statements) = program { + for stmt in statements { + self.execute_statement(&stmt)?; + } + Ok(()) + } else { + Err(InterpreterError::Runtime( + "Expected program node".to_string(), + )) + } + } + + fn execute_statement(&mut self, stmt: &AstNode) -> Result<(), InterpreterError> { + match stmt { + AstNode::VariableDeclaration { + name, + type_annotation: _, + initializer, + is_constant: _, + } => { + let value = if let Some(init) = initializer { + self.evaluate_expression(init)? + } else { + Value::Null + }; + self.set_variable(name.clone(), value); + Ok(()) + } + + AstNode::AnchorDeclaration { name, source } => { + // Anchor saves the current value of a variable + let value = self.evaluate_expression(source)?; + self.set_variable(name.clone(), value); + Ok(()) + } + + AstNode::FunctionDeclaration { + name, + parameters, + return_type: _, + body, + } => { + let param_names: Vec = parameters.iter().map(|p| p.name.clone()).collect(); + let func = FunctionValue::new_global(name.clone(), param_names, body.clone()); + self.set_variable(name.clone(), Value::Function(func)); + Ok(()) + } + + AstNode::TriggerDeclaration { + name, + parameters, + return_type: _, + body, + } => { + // Triggers are handled like functions + let param_names: Vec = parameters.iter().map(|p| p.name.clone()).collect(); + let func = FunctionValue::new_global(name.clone(), param_names, body.clone()); + self.set_variable(name.clone(), Value::Function(func)); + Ok(()) + } + + AstNode::SessionDeclaration { name, members } => { + let session = self.build_session_definition(name, members)?; + self.set_variable(name.clone(), Value::Session(session.clone())); + self.initialize_static_fields(session)?; + Ok(()) + } + + AstNode::EntranceBlock(statements) | AstNode::FinaleBlock(statements) => { + for stmt in statements { + self.execute_statement(stmt)?; + } + Ok(()) + } + + AstNode::ObserveStatement(expr) => { + let value = self.evaluate_expression(expr)?; + CoreBuiltins::observe(&value.to_string()); + Ok(()) + } + + AstNode::WhisperStatement(expr) => { + let value = self.evaluate_expression(expr)?; + CoreBuiltins::whisper(&value.to_string()); + Ok(()) + } + + AstNode::CommandStatement(expr) => { + let value = self.evaluate_expression(expr)?; + CoreBuiltins::command(&value.to_string()); + Ok(()) + } + + AstNode::OscillateStatement { target } => { + // Toggle a boolean variable + if let AstNode::Identifier(name) = target.as_ref() { + match self.get_variable(name) { + Ok(value) => match value { + Value::Boolean(b) => { + self.set_variable(name.clone(), Value::Boolean(!b)); + Ok(()) + } + _ => Err(InterpreterError::Runtime(format!( + "Oscillate target '{}' must be boolean, got {:?}", + name, value + ))), + }, + Err(e) => Err(e), + } + } else { + Err(InterpreterError::Runtime( + "Oscillate requires a variable identifier".to_string(), + )) + } + } + + AstNode::IfStatement { + condition, + then_branch, + else_branch, + } => { + let cond_value = self.evaluate_expression(condition)?; + if cond_value.is_truthy() { + for stmt in then_branch { + self.execute_statement(stmt)?; + } + } else if let Some(else_stmts) = else_branch { + for stmt in else_stmts { + self.execute_statement(stmt)?; + } + } + Ok(()) + } + + AstNode::DeepFocusStatement { condition, body } => { + // DeepFocus is like if but with deeper scope/emphasis + let cond_value = self.evaluate_expression(condition)?; + if cond_value.is_truthy() { + for stmt in body { + self.execute_statement(stmt)?; + } + } + Ok(()) + } + + AstNode::WhileStatement { condition, body } => { + loop { + let cond_value = self.evaluate_expression(condition)?; + if !cond_value.is_truthy() { + break; + } + + match self.execute_block(body) { + Err(InterpreterError::BreakOutsideLoop) => break, + Err(InterpreterError::ContinueOutsideLoop) => continue, + Err(e) => return Err(e), + Ok(()) => {} + } + } + Ok(()) + } + + AstNode::LoopStatement { body } => { + loop { + match self.execute_block(body) { + Err(InterpreterError::BreakOutsideLoop) => break, + Err(InterpreterError::ContinueOutsideLoop) => continue, + Err(e) => return Err(e), + Ok(()) => {} + } + } + Ok(()) + } + + AstNode::ReturnStatement(value) => { + let ret_value = if let Some(expr) = value { + self.evaluate_expression(expr)? + } else { + Value::Null + }; + Err(InterpreterError::Return(ret_value)) + } + + AstNode::BreakStatement => Err(InterpreterError::BreakOutsideLoop), + + AstNode::ContinueStatement => Err(InterpreterError::ContinueOutsideLoop), + + AstNode::ExpressionStatement(expr) => { + self.evaluate_expression(expr)?; + Ok(()) + } + + _ => Err(InterpreterError::Runtime(format!( + "Unsupported statement: {:?}", + stmt + ))), + } + } + + fn execute_block(&mut self, statements: &[AstNode]) -> Result<(), InterpreterError> { + self.push_scope(); + let result = (|| { + for stmt in statements { + self.execute_statement(stmt)?; + } + Ok(()) + })(); + self.pop_scope(); + result + } + + fn evaluate_expression(&mut self, expr: &AstNode) -> Result { + match expr { + AstNode::NumberLiteral(n) => Ok(Value::Number(*n)), + + AstNode::StringLiteral(s) => Ok(Value::String(s.clone())), + + AstNode::BooleanLiteral(b) => Ok(Value::Boolean(*b)), + + AstNode::Identifier(name) => self.get_variable(name), + + AstNode::ArrayLiteral(elements) => { + let mut values = Vec::new(); + for elem in elements { + values.push(self.evaluate_expression(elem)?); + } + Ok(Value::Array(values)) + } + + AstNode::BinaryExpression { + left, + operator, + right, + } => { + let left_val = self.evaluate_expression(left)?; + let right_val = self.evaluate_expression(right)?; + self.evaluate_binary_op(&left_val, operator, &right_val) + } + + AstNode::UnaryExpression { operator, operand } => { + let operand_val = self.evaluate_expression(operand)?; + match operator.as_str() { + "-" => Ok(Value::Number(-operand_val.to_number()?)), + "!" => Ok(Value::Boolean(!operand_val.is_truthy())), + _ => Err(InterpreterError::Runtime(format!( + "Unknown unary operator: {}", + operator + ))), + } + } + + AstNode::CallExpression { callee, arguments } => self.evaluate_call(callee, arguments), + + AstNode::MemberExpression { object, property } => { + let owner = self.evaluate_expression(object)?; + self.resolve_member_value(owner, property) + } + + AstNode::AssignmentExpression { target, value } => match target.as_ref() { + AstNode::Identifier(name) => { + let val = self.evaluate_expression(value)?; + self.set_variable(name.clone(), val.clone()); + Ok(val) + } + AstNode::MemberExpression { object, property } => { + let owner = self.evaluate_expression(object)?; + let val = self.evaluate_expression(value)?; + self.assign_member_value(owner, property, val.clone())?; + Ok(val) + } + _ => Err(InterpreterError::Runtime(localized( + "Invalid assignment target", + "Ungültiges Zuweisungsziel", + ))), + }, + + AstNode::IndexExpression { object, index } => { + let obj = self.evaluate_expression(object)?; + let idx = self.evaluate_expression(index)?; + + if let Value::Array(arr) = obj { + let i = idx.to_number()? as usize; + arr.get(i).cloned().ok_or_else(|| { + InterpreterError::Runtime(format!("Index {} out of bounds", i)) + }) + } else { + Err(InterpreterError::TypeError( + "Cannot index non-array".to_string(), + )) + } + } + + _ => Err(InterpreterError::Runtime(format!( + "Unsupported expression: {:?}", + expr + ))), + } + } + + fn evaluate_binary_op( + &self, + left: &Value, + op: &str, + right: &Value, + ) -> Result { + let normalized = op.to_ascii_lowercase(); + + match normalized.as_str() { + "+" => { + if let (Value::String(s1), Value::String(s2)) = (left, right) { + Ok(Value::String(format!("{}{}", s1, s2))) + } else { + Ok(Value::Number(left.to_number()? + right.to_number()?)) + } + } + "-" => Ok(Value::Number(left.to_number()? - right.to_number()?)), + "*" => Ok(Value::Number(left.to_number()? * right.to_number()?)), + "/" => Ok(Value::Number(left.to_number()? / right.to_number()?)), + "%" => Ok(Value::Number(left.to_number()? % right.to_number()?)), + "==" | "youarefeelingverysleepy" => Ok(Value::Boolean(self.values_equal(left, right))), + "!=" | "youcannotresist" | "notsodeep" => { + Ok(Value::Boolean(!self.values_equal(left, right))) + } + ">" | "lookatthewatch" => Ok(Value::Boolean(left.to_number()? > right.to_number()?)), + "<" | "fallundermyspell" => Ok(Value::Boolean(left.to_number()? < right.to_number()?)), + ">=" | "deeplygreater" | "youreyesaregettingheavy" => { + Ok(Value::Boolean(left.to_number()? >= right.to_number()?)) + } + "<=" | "deeplyless" | "goingdeeper" => { + Ok(Value::Boolean(left.to_number()? <= right.to_number()?)) + } + "&&" | "undermycontrol" => Ok(Value::Boolean(left.is_truthy() && right.is_truthy())), + "||" | "resistanceisfutile" => { + Ok(Value::Boolean(left.is_truthy() || right.is_truthy())) + } + _ => Err(InterpreterError::Runtime(format!( + "Unknown binary operator: {}", + op + ))), + } + } + + fn values_equal(&self, left: &Value, right: &Value) -> bool { + match (left, right) { + (Value::Number(a), Value::Number(b)) => (a - b).abs() < f64::EPSILON, + (Value::String(a), Value::String(b)) => a == b, + (Value::Boolean(a), Value::Boolean(b)) => a == b, + (Value::Null, Value::Null) => true, + _ => false, + } + } + + fn evaluate_call( + &mut self, + callee: &AstNode, + arguments: &[AstNode], + ) -> Result { + let args: Vec = arguments + .iter() + .map(|arg| self.evaluate_expression(arg)) + .collect::>()?; + + if let AstNode::Identifier(name) = callee { + if let Some(result) = self.call_builtin(name, &args)? { + return Ok(result); + } + + let callee_value = self.get_variable(name)?; + return self.invoke_callable(&callee_value, &args); + } + + let callee_value = self.evaluate_expression(callee)?; + self.invoke_callable(&callee_value, &args) + } + + fn invoke_callable( + &mut self, + callee: &Value, + args: &[Value], + ) -> Result { + match callee { + Value::Function(func) => self.call_function(func, args), + Value::Session(session) => self.instantiate_session(session.clone(), args), + Value::Null => Err(InterpreterError::Runtime(localized( + "Cannot call null value", + "Null-Wert kann nicht aufgerufen werden", + ))), + _ => Err(InterpreterError::Runtime(localized( + "Value is not callable", + "Wert ist nicht aufrufbar", + ))), + } + } + + fn call_function( + &mut self, + function: &FunctionValue, + args: &[Value], + ) -> Result { + if function.parameters.len() != args.len() { + return Err(InterpreterError::Runtime(localized( + &format!( + "Expected {} arguments, received {}", + function.parameters.len(), + args.len() + ), + &format!( + "Erwartet {} Argumente, erhalten {}", + function.parameters.len(), + args.len() + ), + ))); + } + + let session_name = function.session_name().map(|name| name.to_string()); + if session_name.is_some() { + self.execution_context.push(ExecutionContextFrame { + session_name: session_name.clone(), + }); + } + + self.push_scope(); + + if let Some(instance) = function.this_binding() { + self.set_variable("this".to_string(), Value::Instance(instance)); + } + + for (param, arg) in function.parameters.iter().zip(args.iter()) { + self.set_variable(param.clone(), arg.clone()); + } + + let result = (|| { + for stmt in &function.body { + self.execute_statement(stmt)?; + } + Ok(Value::Null) + })(); + + self.pop_scope(); + + if session_name.is_some() { + self.execution_context.pop(); + } + + match result { + Err(InterpreterError::Return(val)) => Ok(val), + Err(e) => Err(e), + Ok(value) => Ok(value), + } + } + + fn build_session_definition( + &mut self, + name: &str, + members: &[SessionMember], + ) -> Result, InterpreterError> { + let mut definition = SessionDefinition::new(name.to_string()); + + for member in members { + match member { + SessionMember::Field(field) => { + self.register_session_field(&mut definition, field)? + } + SessionMember::Method(method) => { + self.register_session_method(&mut definition, method)? + } + } + } + + Ok(Rc::new(definition)) + } + + fn register_session_field( + &self, + definition: &mut SessionDefinition, + field: &SessionField, + ) -> Result<(), InterpreterError> { + let initializer = field.initializer.as_ref().map(|expr| (**expr).clone()); + let field_def = SessionFieldDefinition { + name: field.name.clone(), + type_annotation: field.type_annotation.clone(), + visibility: field.visibility, + initializer: initializer.clone(), + }; + + if field.is_static { + definition.push_static_field(field_def, initializer) + } else { + definition.push_field(field_def) + } + } + + fn register_session_method( + &self, + definition: &mut SessionDefinition, + method: &SessionMethod, + ) -> Result<(), InterpreterError> { + if method.is_constructor && method.is_static { + return Err(InterpreterError::Runtime(localized( + &format!( + "Constructor in session '{}' cannot be static", + definition.name() + ), + &format!( + "Konstruktor in Session '{}' darf nicht statisch sein", + definition.name() + ), + ))); + } + + let parameters = method.parameters.iter().map(|p| p.name.clone()).collect(); + + let method_def = SessionMethodDefinition { + name: method.name.clone(), + parameters, + body: method.body.clone(), + visibility: method.visibility, + is_static: method.is_static, + is_constructor: method.is_constructor, + }; + + definition.push_method(method_def) + } + + fn initialize_static_fields( + &mut self, + session: Rc, + ) -> Result<(), InterpreterError> { + if session.static_field_order().is_empty() { + return Ok(()); + } + + self.execution_context.push(ExecutionContextFrame { + session_name: Some(session.name().to_string()), + }); + + let result = (|| { + for field_name in session.static_field_order().to_vec() { + if let Some(initializer) = session.take_static_field_initializer(&field_name) { + let value = self.evaluate_expression(&initializer)?; + session.set_static_field_value(&field_name, value)?; + } + } + Ok(()) + })(); + + self.execution_context.pop(); + result + } + + fn instantiate_session( + &mut self, + session: Rc, + args: &[Value], + ) -> Result { + let instance = Rc::new(RefCell::new(SessionInstance::new(session.clone()))); + self.initialize_instance_fields(instance.clone())?; + + if let Some(constructor) = session.constructor() { + if constructor.parameters.len() != args.len() { + return Err(InterpreterError::Runtime(localized( + &format!( + "Constructor for session '{}' expects {} arguments, received {}", + session.name(), + constructor.parameters.len(), + args.len() + ), + &format!( + "Konstruktor der Session '{}' erwartet {} Argumente, erhalten {}", + session.name(), + constructor.parameters.len(), + args.len() + ), + ))); + } + + let function = FunctionValue::new_session_member( + session.name().to_string(), + constructor, + Some(instance.clone()), + ); + self.call_function(&function, args)?; + } else if !args.is_empty() { + return Err(InterpreterError::Runtime(localized( + &format!( + "Session '{}' does not define a constructor but arguments were provided", + session.name() + ), + &format!( + "Session '{}' definiert keinen Konstruktor, dennoch wurden Argumente übergeben", + session.name() + ), + ))); + } + + Ok(Value::Instance(instance)) + } + + fn initialize_instance_fields( + &mut self, + instance: Rc>, + ) -> Result<(), InterpreterError> { + let definition = { + let borrow = instance.borrow(); + borrow.definition() + }; + + if definition.field_order().is_empty() { + return Ok(()); + } + + self.execution_context.push(ExecutionContextFrame { + session_name: Some(definition.name().to_string()), + }); + self.push_scope(); + self.set_variable("this".to_string(), Value::Instance(instance.clone())); + + let result = (|| { + for field_name in definition.field_order().to_vec() { + if let Some(field_def) = definition.get_field_definition(&field_name) { + if let Some(initializer) = &field_def.initializer { + let value = self.evaluate_expression(initializer)?; + instance.borrow_mut().set_field(&field_name, value); + } + } + } + Ok(()) + })(); + + self.pop_scope(); + self.execution_context.pop(); + result + } + + fn resolve_member_value( + &mut self, + target: Value, + property: &str, + ) -> Result { + match target { + Value::Instance(instance_rc) => { + let definition = { + let borrow = instance_rc.borrow(); + borrow.definition() + }; + + if let Some(method_def) = definition.get_method_definition(property) { + self.ensure_visibility( + method_def.visibility, + definition.name(), + "method", + property, + )?; + let function = FunctionValue::new_session_member( + definition.name().to_string(), + method_def, + Some(instance_rc.clone()), + ); + return Ok(Value::Function(function)); + } + + if let Some(field_def) = definition.get_field_definition(property) { + self.ensure_visibility( + field_def.visibility, + definition.name(), + "field", + property, + )?; + return Ok(instance_rc + .borrow() + .get_field(property) + .unwrap_or(Value::Null)); + } + + if let Some(static_field) = definition.get_static_field_snapshot(property) { + self.ensure_visibility( + static_field.definition.visibility, + definition.name(), + "field", + property, + )?; + return Ok(static_field.value); + } + + if let Some(static_method) = definition.get_static_method_definition(property) { + self.ensure_visibility( + static_method.visibility, + definition.name(), + "method", + property, + )?; + let function = FunctionValue::new_session_member( + definition.name().to_string(), + static_method, + None, + ); + return Ok(Value::Function(function)); + } + + Err(InterpreterError::Runtime(localized( + &format!( + "Session instance of '{}' has no member '{}'", + definition.name(), + property + ), + &format!( + "Session-Instanz von '{}' besitzt kein Mitglied '{}'", + definition.name(), + property + ), + ))) + } + Value::Session(session_rc) => { + if let Some(static_field) = session_rc.get_static_field_snapshot(property) { + self.ensure_visibility( + static_field.definition.visibility, + session_rc.name(), + "field", + property, + )?; + return Ok(static_field.value); + } + + if let Some(method_def) = session_rc.get_static_method_definition(property) { + self.ensure_visibility( + method_def.visibility, + session_rc.name(), + "method", + property, + )?; + let function = FunctionValue::new_session_member( + session_rc.name().to_string(), + method_def, + None, + ); + return Ok(Value::Function(function)); + } + + Err(InterpreterError::Runtime(localized( + &format!( + "Session '{}' has no static member '{}'", + session_rc.name(), + property + ), + &format!( + "Session '{}' besitzt kein statisches Mitglied '{}'", + session_rc.name(), + property + ), + ))) + } + other => Err(InterpreterError::Runtime(localized( + &format!("Cannot access member '{}' on value '{}'", property, other), + &format!( + "Mitglied '{}' kann auf Wert '{}' nicht zugegriffen werden", + property, other + ), + ))), + } + } + + fn assign_member_value( + &mut self, + target: Value, + property: &str, + value: Value, + ) -> Result<(), InterpreterError> { + match target { + Value::Instance(instance_rc) => { + let definition = { + let borrow = instance_rc.borrow(); + borrow.definition() + }; + + if let Some(field_def) = definition.get_field_definition(property) { + self.ensure_visibility( + field_def.visibility, + definition.name(), + "field", + property, + )?; + instance_rc.borrow_mut().set_field(property, value); + return Ok(()); + } + + if definition.get_method_definition(property).is_some() + || definition.get_static_method_definition(property).is_some() + { + return Err(InterpreterError::Runtime(localized( + &format!("Cannot assign to method '{}'", property), + &format!("Zuweisung zur Methode '{}' nicht möglich", property), + ))); + } + + if definition.get_static_field_snapshot(property).is_some() { + return Err(InterpreterError::Runtime(localized( + &format!( + "Assign static field '{}' through session '{}', not an instance", + property, + definition.name() + ), + &format!( + "Statisches Feld '{}' muss über die Session '{}' gesetzt werden", + property, + definition.name() + ), + ))); + } + + Err(InterpreterError::Runtime(localized( + &format!( + "Session instance of '{}' has no field '{}'", + definition.name(), + property + ), + &format!( + "Session-Instanz von '{}' besitzt kein Feld '{}'", + definition.name(), + property + ), + ))) + } + Value::Session(session_rc) => { + if let Some(static_field) = session_rc.get_static_field_snapshot(property) { + self.ensure_visibility( + static_field.definition.visibility, + session_rc.name(), + "field", + property, + )?; + session_rc.set_static_field_value(property, value)?; + return Ok(()); + } + + if session_rc.get_static_method_definition(property).is_some() { + return Err(InterpreterError::Runtime(localized( + &format!("Cannot assign to static method '{}'", property), + &format!( + "Zuweisung zu statischer Methode '{}' nicht möglich", + property + ), + ))); + } + + Err(InterpreterError::Runtime(localized( + &format!( + "Session '{}' has no static field '{}'", + session_rc.name(), + property + ), + &format!( + "Session '{}' besitzt kein statisches Feld '{}'", + session_rc.name(), + property + ), + ))) + } + _ => Err(InterpreterError::Runtime(localized( + "Assignment target is not a session member", + "Zuweisungsziel ist kein Session-Mitglied", + ))), + } + } + + fn ensure_visibility( + &self, + visibility: SessionVisibility, + session_name: &str, + member_kind: &str, + member_name: &str, + ) -> Result<(), InterpreterError> { + if visibility == SessionVisibility::Private && !self.is_access_allowed(session_name) { + return Err(InterpreterError::Runtime(localized( + &format!( + "Access denied to private {} '{}' of session '{}'", + member_kind, member_name, session_name + ), + &format!( + "Zugriff auf privates {} '{}' der Session '{}' verweigert", + member_kind, member_name, session_name + ), + ))); + } + Ok(()) + } + + fn is_access_allowed(&self, session_name: &str) -> bool { + self.execution_context + .iter() + .rev() + .find_map(|frame| frame.session_name.as_deref()) + == Some(session_name) + } + + fn call_builtin( + &mut self, + name: &str, + args: &[Value], + ) -> Result, InterpreterError> { + if let Some(result) = self.call_math_builtin(name, args)? { + return Ok(Some(result)); + } + + if let Some(result) = self.call_string_builtin(name, args)? { + return Ok(Some(result)); + } + + if let Some(result) = self.call_array_builtin(name, args)? { + return Ok(Some(result)); + } + + if let Some(result) = self.call_core_builtin(name, args)? { + return Ok(Some(result)); + } + + if let Some(result) = self.call_file_builtin(name, args)? { + return Ok(Some(result)); + } + + if let Some(result) = self.call_hashing_builtin(name, args)? { + return Ok(Some(result)); + } + + if let Some(result) = self.call_statistics_builtin(name, args)? { + return Ok(Some(result)); + } + + if let Some(result) = self.call_system_builtin(name, args)? { + return Ok(Some(result)); + } + + if let Some(result) = self.call_time_builtin(name, args)? { + return Ok(Some(result)); + } + + if let Some(result) = self.call_validation_builtin(name, args)? { + return Ok(Some(result)); + } + + Ok(None) + } + + fn call_math_builtin( + &self, + name: &str, + args: &[Value], + ) -> Result, InterpreterError> { + let result = match name { + "Sin" => Some(Value::Number(MathBuiltins::sin( + self.number_arg(args, 0, name)?, + ))), + "Cos" => Some(Value::Number(MathBuiltins::cos( + self.number_arg(args, 0, name)?, + ))), + "Tan" => Some(Value::Number(MathBuiltins::tan( + self.number_arg(args, 0, name)?, + ))), + "Sqrt" => Some(Value::Number(MathBuiltins::sqrt( + self.number_arg(args, 0, name)?, + ))), + "Log" => Some(Value::Number(MathBuiltins::log( + self.number_arg(args, 0, name)?, + ))), + "Log10" => Some(Value::Number(MathBuiltins::log10( + self.number_arg(args, 0, name)?, + ))), + "Abs" => Some(Value::Number(MathBuiltins::abs( + self.number_arg(args, 0, name)?, + ))), + "Floor" => Some(Value::Number(MathBuiltins::floor( + self.number_arg(args, 0, name)?, + ))), + "Ceil" => Some(Value::Number(MathBuiltins::ceil( + self.number_arg(args, 0, name)?, + ))), + "Round" => Some(Value::Number(MathBuiltins::round( + self.number_arg(args, 0, name)?, + ))), + "Min" => Some(Value::Number(MathBuiltins::min( + self.number_arg(args, 0, name)?, + self.number_arg(args, 1, name)?, + ))), + "Max" => Some(Value::Number(MathBuiltins::max( + self.number_arg(args, 0, name)?, + self.number_arg(args, 1, name)?, + ))), + "Pow" => Some(Value::Number(MathBuiltins::pow( + self.number_arg(args, 0, name)?, + self.number_arg(args, 1, name)?, + ))), + "Factorial" => Some(Value::Number(MathBuiltins::factorial( + self.integer_arg(args, 0, name)?, + ) as f64)), + "Gcd" => Some(Value::Number(MathBuiltins::gcd( + self.integer_arg(args, 0, name)?, + self.integer_arg(args, 1, name)?, + ) as f64)), + "Lcm" => Some(Value::Number(MathBuiltins::lcm( + self.integer_arg(args, 0, name)?, + self.integer_arg(args, 1, name)?, + ) as f64)), + "IsPrime" => Some(Value::Boolean(MathBuiltins::is_prime( + self.integer_arg(args, 0, name)?, + ))), + "Fibonacci" => Some(Value::Number(MathBuiltins::fibonacci( + self.integer_arg(args, 0, name)?, + ) as f64)), + "Clamp" => Some(Value::Number(MathBuiltins::clamp( + self.number_arg(args, 0, name)?, + self.number_arg(args, 1, name)?, + self.number_arg(args, 2, name)?, + ))), + _ => None, + }; + + Ok(result) + } + + fn call_string_builtin( + &self, + name: &str, + args: &[Value], + ) -> Result, InterpreterError> { + let result = match name { + "Length" => Some(Value::Number( + StringBuiltins::length(&self.string_arg(args, 0, name)?) as f64, + )), + "ToUpper" => Some(Value::String(StringBuiltins::to_upper( + &self.string_arg(args, 0, name)?, + ))), + "ToLower" => Some(Value::String(StringBuiltins::to_lower( + &self.string_arg(args, 0, name)?, + ))), + "Trim" => Some(Value::String(StringBuiltins::trim( + &self.string_arg(args, 0, name)?, + ))), + "IndexOf" => Some(Value::Number(StringBuiltins::index_of( + &self.string_arg(args, 0, name)?, + &self.string_arg(args, 1, name)?, + ) as f64)), + "Replace" => Some(Value::String(StringBuiltins::replace( + &self.string_arg(args, 0, name)?, + &self.string_arg(args, 1, name)?, + &self.string_arg(args, 2, name)?, + ))), + "Reverse" => Some(Value::String(StringBuiltins::reverse( + &self.string_arg(args, 0, name)?, + ))), + "Capitalize" => Some(Value::String(StringBuiltins::capitalize( + &self.string_arg(args, 0, name)?, + ))), + "StartsWith" => Some(Value::Boolean(StringBuiltins::starts_with( + &self.string_arg(args, 0, name)?, + &self.string_arg(args, 1, name)?, + ))), + "EndsWith" => Some(Value::Boolean(StringBuiltins::ends_with( + &self.string_arg(args, 0, name)?, + &self.string_arg(args, 1, name)?, + ))), + "Contains" => Some(Value::Boolean(StringBuiltins::contains( + &self.string_arg(args, 0, name)?, + &self.string_arg(args, 1, name)?, + ))), + "Split" => { + let items = StringBuiltins::split( + &self.string_arg(args, 0, name)?, + &self.string_arg(args, 1, name)?, + ) + .into_iter() + .map(Value::String) + .collect(); + Some(Value::Array(items)) + } + "Substring" => Some(Value::String(StringBuiltins::substring( + &self.string_arg(args, 0, name)?, + self.usize_arg(args, 1, name)?, + self.usize_arg(args, 2, name)?, + ))), + "Repeat" => Some(Value::String(StringBuiltins::repeat( + &self.string_arg(args, 0, name)?, + self.usize_arg(args, 1, name)?, + ))), + "PadLeft" => Some(Value::String(StringBuiltins::pad_left( + &self.string_arg(args, 0, name)?, + self.usize_arg(args, 1, name)?, + self.char_arg(args, 2, name)?, + ))), + "PadRight" => Some(Value::String(StringBuiltins::pad_right( + &self.string_arg(args, 0, name)?, + self.usize_arg(args, 1, name)?, + self.char_arg(args, 2, name)?, + ))), + "IsEmpty" => Some(Value::Boolean(StringBuiltins::is_empty( + &self.string_arg(args, 0, name)?, + ))), + "IsWhitespace" => Some(Value::Boolean(StringBuiltins::is_whitespace( + &self.string_arg(args, 0, name)?, + ))), + _ => None, + }; + + Ok(result) + } + + fn call_array_builtin( + &self, + name: &str, + args: &[Value], + ) -> Result, InterpreterError> { + let result = match name { + "ArrayLength" => { + let array = self.array_arg(args, 0, name)?; + Some(Value::Number(ArrayBuiltins::length(&array) as f64)) + } + "ArrayIsEmpty" => { + let array = self.array_arg(args, 0, name)?; + Some(Value::Boolean(ArrayBuiltins::is_empty(&array))) + } + "ArrayGet" => { + let array = self.array_arg(args, 0, name)?; + let index = self.usize_arg(args, 1, name)?; + let value = ArrayBuiltins::get(&array, index).unwrap_or(Value::Null); + Some(value) + } + "ArrayIndexOf" => { + let array = self.array_arg(args, 0, name)?; + let target = self.arg(args, 1, name)?.clone(); + Some(Value::Number( + ArrayBuiltins::index_of(&array, &target) as f64 + )) + } + "ArrayContains" => { + let array = self.array_arg(args, 0, name)?; + let target = self.arg(args, 1, name)?.clone(); + Some(Value::Boolean(ArrayBuiltins::contains(&array, &target))) + } + "ArrayReverse" => { + let array = self.array_arg(args, 0, name)?; + Some(Value::Array(ArrayBuiltins::reverse(&array))) + } + "ArraySum" => { + let array = self.array_arg(args, 0, name)?; + let numbers = self.values_to_numbers(&array, name)?; + Some(Value::Number(ArrayBuiltins::sum(&numbers))) + } + "ArrayAverage" => { + let array = self.array_arg(args, 0, name)?; + let numbers = self.values_to_numbers(&array, name)?; + Some(Value::Number(ArrayBuiltins::average(&numbers))) + } + "ArrayMin" => { + let array = self.array_arg(args, 0, name)?; + let numbers = self.values_to_numbers(&array, name)?; + Some(Value::Number(ArrayBuiltins::min(&numbers))) + } + "ArrayMax" => { + let array = self.array_arg(args, 0, name)?; + let numbers = self.values_to_numbers(&array, name)?; + Some(Value::Number(ArrayBuiltins::max(&numbers))) + } + "ArraySort" => { + let array = self.array_arg(args, 0, name)?; + let numbers = self.values_to_numbers(&array, name)?; + let sorted = ArrayBuiltins::sort(&numbers) + .into_iter() + .map(Value::Number) + .collect(); + Some(Value::Array(sorted)) + } + "ArrayFirst" => { + let array = self.array_arg(args, 0, name)?; + Some(ArrayBuiltins::first(&array).unwrap_or(Value::Null)) + } + "ArrayLast" => { + let array = self.array_arg(args, 0, name)?; + Some(ArrayBuiltins::last(&array).unwrap_or(Value::Null)) + } + "ArrayTake" => { + let array = self.array_arg(args, 0, name)?; + let count = self.usize_arg(args, 1, name)?; + Some(Value::Array(ArrayBuiltins::take(&array, count))) + } + "ArraySkip" => { + let array = self.array_arg(args, 0, name)?; + let count = self.usize_arg(args, 1, name)?; + Some(Value::Array(ArrayBuiltins::skip(&array, count))) + } + "ArraySlice" => { + let array = self.array_arg(args, 0, name)?; + let start = self.usize_arg(args, 1, name)?; + let end = self.usize_arg(args, 2, name)?; + Some(Value::Array(ArrayBuiltins::slice(&array, start, end))) + } + "ArrayJoin" => { + let array = self.array_arg(args, 0, name)?; + let separator = self.string_arg(args, 1, name)?; + Some(Value::String(ArrayBuiltins::join(&array, &separator))) + } + "ArrayCount" => { + let array = self.array_arg(args, 0, name)?; + let target = self.arg(args, 1, name)?.clone(); + Some(Value::Number(ArrayBuiltins::count(&array, &target) as f64)) + } + "ArrayDistinct" => { + let array = self.array_arg(args, 0, name)?; + Some(Value::Array(ArrayBuiltins::distinct(&array))) + } + _ => None, + }; + + Ok(result) + } + + fn call_core_builtin( + &self, + name: &str, + args: &[Value], + ) -> Result, InterpreterError> { + let result = match name { + "Observe" => { + let message = self.arg(args, 0, name)?.to_string(); + CoreBuiltins::observe(&message); + Some(Value::Null) + } + "Drift" => { + let duration = self.number_arg(args, 0, name)?; + CoreBuiltins::drift(duration.max(0.0) as u64); + Some(Value::Null) + } + "DeepTrance" => { + let duration = self.number_arg(args, 0, name)?; + CoreBuiltins::deep_trance(duration.max(0.0) as u64); + Some(Value::Null) + } + "HypnoticCountdown" => { + CoreBuiltins::hypnotic_countdown(self.integer_arg(args, 0, name)?); + Some(Value::Null) + } + "TranceInduction" => { + CoreBuiltins::trance_induction(&self.string_arg(args, 0, name)?); + Some(Value::Null) + } + "HypnoticVisualization" => { + CoreBuiltins::hypnotic_visualization(&self.string_arg(args, 0, name)?); + Some(Value::Null) + } + "ToInt" => Some(Value::Number( + CoreBuiltins::to_int(self.number_arg(args, 0, name)?) as f64, + )), + "ToDouble" => Some(Value::Number( + CoreBuiltins::to_double(&self.string_arg(args, 0, name)?) + .map_err(InterpreterError::Runtime)?, + )), + "ToString" => Some(Value::String( + args.first() + .map(|v| v.to_string()) + .unwrap_or_else(|| "null".to_string()), + )), + "ToBoolean" => Some(Value::Boolean(CoreBuiltins::to_boolean( + &self.string_arg(args, 0, name)?, + ))), + _ => None, + }; + + Ok(result) + } + + fn call_file_builtin( + &self, + name: &str, + args: &[Value], + ) -> Result, InterpreterError> { + let result = match name { + "ReadFile" => Some(Value::String( + FileBuiltins::read_file(&self.string_arg(args, 0, name)?) + .map_err(|e| InterpreterError::Runtime(e.to_string()))?, + )), + "WriteFile" => { + FileBuiltins::write_file( + &self.string_arg(args, 0, name)?, + &self.string_arg(args, 1, name)?, + ) + .map_err(|e| InterpreterError::Runtime(e.to_string()))?; + Some(Value::Null) + } + "AppendFile" => { + FileBuiltins::append_file( + &self.string_arg(args, 0, name)?, + &self.string_arg(args, 1, name)?, + ) + .map_err(|e| InterpreterError::Runtime(e.to_string()))?; + Some(Value::Null) + } + "FileExists" => Some(Value::Boolean(FileBuiltins::file_exists( + &self.string_arg(args, 0, name)?, + ))), + "IsFile" => Some(Value::Boolean(FileBuiltins::is_file( + &self.string_arg(args, 0, name)?, + ))), + "IsDirectory" => Some(Value::Boolean(FileBuiltins::is_directory( + &self.string_arg(args, 0, name)?, + ))), + "DeleteFile" => { + FileBuiltins::delete_file(&self.string_arg(args, 0, name)?) + .map_err(|e| InterpreterError::Runtime(e.to_string()))?; + Some(Value::Null) + } + "CreateDirectory" => { + FileBuiltins::create_directory(&self.string_arg(args, 0, name)?) + .map_err(|e| InterpreterError::Runtime(e.to_string()))?; + Some(Value::Null) + } + "ListDirectory" => { + let files = FileBuiltins::list_directory(&self.string_arg(args, 0, name)?) + .map_err(|e| InterpreterError::Runtime(e.to_string()))? + .into_iter() + .map(Value::String) + .collect(); + Some(Value::Array(files)) + } + "GetFileSize" => Some(Value::Number( + FileBuiltins::get_file_size(&self.string_arg(args, 0, name)?) + .map_err(|e| InterpreterError::Runtime(e.to_string()))? as f64, + )), + "CopyFile" => Some(Value::Number( + FileBuiltins::copy_file( + &self.string_arg(args, 0, name)?, + &self.string_arg(args, 1, name)?, + ) + .map_err(|e| InterpreterError::Runtime(e.to_string()))? as f64, + )), + "RenameFile" => { + FileBuiltins::rename_file( + &self.string_arg(args, 0, name)?, + &self.string_arg(args, 1, name)?, + ) + .map_err(|e| InterpreterError::Runtime(e.to_string()))?; + Some(Value::Null) + } + "GetFileExtension" => Some(self.option_string_to_value( + FileBuiltins::get_file_extension(&self.string_arg(args, 0, name)?), + )), + "GetFileName" => Some(self.option_string_to_value(FileBuiltins::get_file_name( + &self.string_arg(args, 0, name)?, + ))), + "GetParentDirectory" => Some(self.option_string_to_value( + FileBuiltins::get_parent_directory(&self.string_arg(args, 0, name)?), + )), + _ => None, + }; + + Ok(result) + } + + fn call_hashing_builtin( + &self, + name: &str, + args: &[Value], + ) -> Result, InterpreterError> { + let result = match name { + "HashString" => Some(Value::Number(HashingBuiltins::hash_string( + &self.string_arg(args, 0, name)?, + ) as f64)), + "HashNumber" => Some(Value::Number(HashingBuiltins::hash_number( + self.number_arg(args, 0, name)?, + ) as f64)), + "SimpleRandom" => Some(Value::Number(HashingBuiltins::simple_random( + self.u64_arg(args, 0, name)?, + ) as f64)), + "AreAnagrams" => Some(Value::Boolean(HashingBuiltins::are_anagrams( + &self.string_arg(args, 0, name)?, + &self.string_arg(args, 1, name)?, + ))), + "IsPalindrome" => Some(Value::Boolean(HashingBuiltins::is_palindrome( + &self.string_arg(args, 0, name)?, + ))), + "CountOccurrences" => Some(Value::Number(HashingBuiltins::count_occurrences( + &self.string_arg(args, 0, name)?, + &self.string_arg(args, 1, name)?, + ) as f64)), + "RemoveDuplicates" => Some(Value::String(HashingBuiltins::remove_duplicates( + &self.string_arg(args, 0, name)?, + ))), + "UniqueCharacters" => Some(Value::String(HashingBuiltins::unique_characters( + &self.string_arg(args, 0, name)?, + ))), + "ReverseWords" => Some(Value::String(HashingBuiltins::reverse_words( + &self.string_arg(args, 0, name)?, + ))), + "TitleCase" => Some(Value::String(HashingBuiltins::title_case( + &self.string_arg(args, 0, name)?, + ))), + _ => None, + }; + + Ok(result) + } + + fn call_statistics_builtin( + &self, + name: &str, + args: &[Value], + ) -> Result, InterpreterError> { + let numbers_primary = |this: &Self| -> Result, InterpreterError> { + let array = this.array_arg(args, 0, name)?; + this.values_to_numbers(&array, name) + }; + + let result = match name { + "Mean" => Some(Value::Number(StatisticsBuiltins::calculate_mean( + &numbers_primary(self)?, + ))), + "Median" => Some(Value::Number(StatisticsBuiltins::calculate_median( + &numbers_primary(self)?, + ))), + "Mode" => Some(Value::Number(StatisticsBuiltins::calculate_mode( + &numbers_primary(self)?, + ))), + "StandardDeviation" => Some(Value::Number( + StatisticsBuiltins::calculate_standard_deviation(&numbers_primary(self)?), + )), + "Variance" => Some(Value::Number(StatisticsBuiltins::calculate_variance( + &numbers_primary(self)?, + ))), + "Range" => Some(Value::Number(StatisticsBuiltins::calculate_range( + &numbers_primary(self)?, + ))), + "Percentile" => Some(Value::Number(StatisticsBuiltins::calculate_percentile( + &numbers_primary(self)?, + self.number_arg(args, 1, name)?, + ))), + "Correlation" => { + let x = self.values_to_numbers(&self.array_arg(args, 0, name)?, name)?; + let y = self.values_to_numbers(&self.array_arg(args, 1, name)?, name)?; + Some(Value::Number(StatisticsBuiltins::calculate_correlation( + &x, &y, + ))) + } + "LinearRegression" => { + let x = self.values_to_numbers(&self.array_arg(args, 0, name)?, name)?; + let y = self.values_to_numbers(&self.array_arg(args, 1, name)?, name)?; + let (slope, intercept) = StatisticsBuiltins::linear_regression(&x, &y); + Some(Value::Array(vec![ + Value::Number(slope), + Value::Number(intercept), + ])) + } + _ => None, + }; + + Ok(result) + } + + fn call_system_builtin( + &self, + name: &str, + args: &[Value], + ) -> Result, InterpreterError> { + let result = match name { + "GetCurrentDirectory" => Some(Value::String(SystemBuiltins::get_current_directory())), + "GetEnv" => Some(self.option_string_to_value(SystemBuiltins::get_env_var( + &self.string_arg(args, 0, name)?, + ))), + "SetEnv" => { + SystemBuiltins::set_env_var( + &self.string_arg(args, 0, name)?, + &self.string_arg(args, 1, name)?, + ); + Some(Value::Null) + } + "GetOperatingSystem" => Some(Value::String(SystemBuiltins::get_operating_system())), + "GetArchitecture" => Some(Value::String(SystemBuiltins::get_architecture())), + "GetCpuCount" => Some(Value::Number(SystemBuiltins::get_cpu_count() as f64)), + "GetHostname" => Some(Value::String(SystemBuiltins::get_hostname())), + "GetUsername" => Some(Value::String(SystemBuiltins::get_username())), + "GetHomeDirectory" => Some(Value::String(SystemBuiltins::get_home_directory())), + "GetTempDirectory" => Some(Value::String(SystemBuiltins::get_temp_directory())), + "GetArgs" => Some(Value::Array( + SystemBuiltins::get_args() + .into_iter() + .map(Value::String) + .collect(), + )), + "Exit" => { + // Exit mirrors the legacy runtime behavior by terminating the host process immediately. + SystemBuiltins::exit(self.integer_arg(args, 0, name)? as i32); + } + _ => None, + }; + + Ok(result) + } + + fn call_time_builtin( + &self, + name: &str, + args: &[Value], + ) -> Result, InterpreterError> { + let result = match name { + "CurrentTimestamp" => Some(Value::Number(TimeBuiltins::get_current_time() as f64)), + "CurrentDate" => Some(Value::String(TimeBuiltins::get_current_date())), + "CurrentTime" => Some(Value::String(TimeBuiltins::get_current_time_string())), + "CurrentDateTime" => Some(Value::String(TimeBuiltins::get_current_date_time())), + "FormatDateTime" => Some(Value::String(TimeBuiltins::format_date_time( + &self.string_arg(args, 0, name)?, + ))), + "DayOfWeek" => Some(Value::Number(TimeBuiltins::get_day_of_week() as f64)), + "DayOfYear" => Some(Value::Number(TimeBuiltins::get_day_of_year() as f64)), + "IsLeapYear" => Some(Value::Boolean(TimeBuiltins::is_leap_year( + self.integer_arg(args, 0, name)? as i32, + ))), + "DaysInMonth" => Some(self.option_u32_to_value(TimeBuiltins::get_days_in_month( + self.integer_arg(args, 0, name)? as i32, + self.usize_arg(args, 1, name)? as u32, + ))), + "CurrentYear" => Some(Value::Number(TimeBuiltins::get_year() as f64)), + "CurrentMonth" => Some(Value::Number(TimeBuiltins::get_month() as f64)), + "CurrentDay" => Some(Value::Number(TimeBuiltins::get_day() as f64)), + "CurrentHour" => Some(Value::Number(TimeBuiltins::get_hour() as f64)), + "CurrentMinute" => Some(Value::Number(TimeBuiltins::get_minute() as f64)), + "CurrentSecond" => Some(Value::Number(TimeBuiltins::get_second() as f64)), + _ => None, + }; + + Ok(result) + } + + fn call_validation_builtin( + &self, + name: &str, + args: &[Value], + ) -> Result, InterpreterError> { + let result = match name { + "IsValidEmail" => Some(Value::Boolean(ValidationBuiltins::is_valid_email( + &self.string_arg(args, 0, name)?, + ))), + "IsValidUrl" => Some(Value::Boolean(ValidationBuiltins::is_valid_url( + &self.string_arg(args, 0, name)?, + ))), + "IsValidPhoneNumber" => Some(Value::Boolean( + ValidationBuiltins::is_valid_phone_number(&self.string_arg(args, 0, name)?), + )), + "IsAlphanumeric" => Some(Value::Boolean(ValidationBuiltins::is_alphanumeric( + &self.string_arg(args, 0, name)?, + ))), + "IsAlphabetic" => Some(Value::Boolean(ValidationBuiltins::is_alphabetic( + &self.string_arg(args, 0, name)?, + ))), + "IsNumeric" => Some(Value::Boolean(ValidationBuiltins::is_numeric( + &self.string_arg(args, 0, name)?, + ))), + "IsLowercase" => Some(Value::Boolean(ValidationBuiltins::is_lowercase( + &self.string_arg(args, 0, name)?, + ))), + "IsUppercase" => Some(Value::Boolean(ValidationBuiltins::is_uppercase( + &self.string_arg(args, 0, name)?, + ))), + "IsInRange" => Some(Value::Boolean(ValidationBuiltins::is_in_range( + self.number_arg(args, 0, name)?, + self.number_arg(args, 1, name)?, + self.number_arg(args, 2, name)?, + ))), + "MatchesPattern" => Some(Value::Boolean(ValidationBuiltins::matches_pattern( + &self.string_arg(args, 0, name)?, + &self.string_arg(args, 1, name)?, + ))), + _ => None, + }; + + Ok(result) + } + + fn arg<'a>( + &self, + args: &'a [Value], + index: usize, + name: &str, + ) -> Result<&'a Value, InterpreterError> { + args.get(index).ok_or_else(|| { + InterpreterError::Runtime(format!( + "Builtin '{}' expected argument at position {}", + name, + index + 1 + )) + }) + } + + fn number_arg( + &self, + args: &[Value], + index: usize, + name: &str, + ) -> Result { + self.arg(args, index, name)?.to_number().map_err(|_| { + InterpreterError::TypeError(format!( + "Builtin '{}' expected numeric argument at position {}", + name, + index + 1 + )) + }) + } + + fn integer_arg( + &self, + args: &[Value], + index: usize, + name: &str, + ) -> Result { + let value = self.number_arg(args, index, name)?; + Ok(value.round() as i64) + } + + fn u64_arg(&self, args: &[Value], index: usize, name: &str) -> Result { + let value = self.number_arg(args, index, name)?; + if value < 0.0 { + return Err(InterpreterError::TypeError(format!( + "Builtin '{}' expected non-negative number at position {}", + name, + index + 1 + ))); + } + Ok(value.round() as u64) + } + + fn usize_arg( + &self, + args: &[Value], + index: usize, + name: &str, + ) -> Result { + let value = self.number_arg(args, index, name)?; + if value < 0.0 { + return Err(InterpreterError::TypeError(format!( + "Builtin '{}' expected non-negative number at position {}", + name, + index + 1 + ))); + } + Ok(value.round() as usize) + } + + fn string_arg( + &self, + args: &[Value], + index: usize, + name: &str, + ) -> Result { + match self.arg(args, index, name)? { + Value::String(s) => Ok(s.clone()), + other => Err(InterpreterError::TypeError(format!( + "Builtin '{}' expected string argument at position {}, got {:?}", + name, + index + 1, + other + ))), + } + } + + fn char_arg(&self, args: &[Value], index: usize, name: &str) -> Result { + let text = self.string_arg(args, index, name)?; + text.chars().next().ok_or_else(|| { + InterpreterError::TypeError(format!( + "Builtin '{}' expected non-empty string to derive character at position {}", + name, + index + 1 + )) + }) + } + + fn array_arg( + &self, + args: &[Value], + index: usize, + name: &str, + ) -> Result, InterpreterError> { + match self.arg(args, index, name)? { + Value::Array(items) => Ok(items.clone()), + other => Err(InterpreterError::TypeError(format!( + "Builtin '{}' expected array argument at position {}, got {:?}", + name, + index + 1, + other + ))), + } + } + + fn option_string_to_value(&self, input: Option) -> Value { + input.map(Value::String).unwrap_or(Value::Null) + } + + fn option_u32_to_value(&self, input: Option) -> Value { + input + .map(|v| Value::Number(v as f64)) + .unwrap_or(Value::Null) + } + + fn values_to_numbers( + &self, + values: &[Value], + name: &str, + ) -> Result, InterpreterError> { + values + .iter() + .enumerate() + .map(|(i, value)| { + value.to_number().map_err(|_| { + InterpreterError::TypeError(format!( + "Builtin '{}' expected numeric array element at position {}", + name, + i + 1 + )) + }) + }) + .collect() + } + + fn push_scope(&mut self) { + self.locals.push(HashMap::new()); + } + + fn pop_scope(&mut self) { + self.locals.pop(); + } + + fn set_variable(&mut self, name: String, value: Value) { + if let Some(scope) = self.locals.last_mut() { + scope.insert(name, value); + } else { + self.globals.insert(name, value); + } + } + + fn get_variable(&self, name: &str) -> Result { + // Search in local scopes (from innermost to outermost) + for scope in self.locals.iter().rev() { + if let Some(value) = scope.get(name) { + return Ok(value.clone()); + } + } + + // Search in global scope + self.globals + .get(name) + .cloned() + .ok_or_else(|| InterpreterError::UndefinedVariable(name.to_string())) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use hypnoscript_lexer_parser::{Lexer, Parser}; + + #[test] + fn test_simple_program() { + let source = r#" +Focus { + induce x: number = 42; + induce y: number = 10; + induce sum: number = x + y; +} Relax +"#; + let mut lexer = Lexer::new(source); + let tokens = lexer.lex().unwrap(); + let mut parser = Parser::new(tokens); + let ast = parser.parse_program().unwrap(); + + let mut interpreter = Interpreter::new(); + let result = interpreter.execute_program(ast); + assert!(result.is_ok()); + } + + #[test] + fn test_if_statement() { + let source = r#" +Focus { + induce x: number = 10; + if (x > 5) deepFocus { + induce result: number = 1; + } +} Relax +"#; + let mut lexer = Lexer::new(source); + let tokens = lexer.lex().unwrap(); + let mut parser = Parser::new(tokens); + let ast = parser.parse_program().unwrap(); + + let mut interpreter = Interpreter::new(); + let result = interpreter.execute_program(ast); + assert!(result.is_ok()); + } + + #[test] + fn test_session_constructor_and_methods() { + let source = r#" +Focus { + session Counter { + expose value: number; + + suggestion constructor(initial: number) { + this.value = initial; + } + + suggestion inc() { + this.value = this.value + 1; + } + + suggestion current(): number { + awaken this.value; + } + } + + induce counter = Counter(5); + counter.inc(); + counter.inc(); + induce current: number = counter.current(); +} Relax +"#; + + let mut lexer = Lexer::new(source); + let tokens = lexer.lex().unwrap(); + let mut parser = Parser::new(tokens); + let ast = parser.parse_program().unwrap(); + + let mut interpreter = Interpreter::new(); + interpreter.execute_program(ast).unwrap(); + + let current = interpreter.get_variable("current").unwrap(); + assert_eq!(current, Value::Number(7.0)); + } + + #[test] + fn test_hypnotic_operator_synonyms_execution() { + let source = r#" +Focus { + induce a: number = 10; + induce b: number = 5; + + induce eq: boolean = a youAreFeelingVerySleepy b; + induce neq: boolean = a youCannotResist b; + induce ge: boolean = a yourEyesAreGettingHeavy 9; + induce le: boolean = b goingDeeper 4; + induce both: boolean = ge underMyControl neq; + induce either: boolean = le resistanceIsFutile eq; +} Relax +"#; + + let mut lexer = Lexer::new(source); + let tokens = lexer.lex().unwrap(); + let mut parser = Parser::new(tokens); + let ast = parser.parse_program().unwrap(); + + let mut interpreter = Interpreter::new(); + interpreter.execute_program(ast).unwrap(); + + assert_eq!( + interpreter.get_variable("eq").unwrap(), + Value::Boolean(false) + ); + assert_eq!( + interpreter.get_variable("neq").unwrap(), + Value::Boolean(true) + ); + assert_eq!( + interpreter.get_variable("ge").unwrap(), + Value::Boolean(true) + ); + assert_eq!( + interpreter.get_variable("le").unwrap(), + Value::Boolean(false) + ); + assert_eq!( + interpreter.get_variable("both").unwrap(), + Value::Boolean(true) + ); + assert_eq!( + interpreter.get_variable("either").unwrap(), + Value::Boolean(false) + ); + } + + #[test] + fn test_private_field_access_rejected() { + let source = r#" +Focus { + session Account { + conceal balance: number; + + suggestion constructor(amount: number) { + this.balance = amount; + } + + suggestion read(): number { + awaken this.balance; + } + } + + induce account = Account(100); + // The following line should fail because balance is private + induce leaked = account.balance; +} Relax +"#; + + let mut lexer = Lexer::new(source); + let tokens = lexer.lex().unwrap(); + let mut parser = Parser::new(tokens); + let ast = parser.parse_program().unwrap(); + + let mut interpreter = Interpreter::new(); + let result = interpreter.execute_program(ast); + assert!(matches!( + result, + Err(InterpreterError::Runtime(message)) if message.contains("Access denied") + )); + } + + #[test] + fn test_static_field_and_method() { + let source = r#" +Focus { + session Config { + dominant expose version: string = "1.0"; + + dominant suggestion setVersion(newVersion: string) { + Config.version = newVersion; + } + } + + Config.setVersion("2.5"); + induce activeVersion: string = Config.version; +} Relax +"#; + + let mut lexer = Lexer::new(source); + let tokens = lexer.lex().unwrap(); + let mut parser = Parser::new(tokens); + let ast = parser.parse_program().unwrap(); + + let mut interpreter = Interpreter::new(); + interpreter.execute_program(ast).unwrap(); + + let result = interpreter.get_variable("activeVersion").unwrap(); + assert_eq!(result, Value::String("2.5".to_string())); + } +} diff --git a/hypnoscript-compiler/src/lib.rs b/hypnoscript-compiler/src/lib.rs new file mode 100644 index 0000000..9645992 --- /dev/null +++ b/hypnoscript-compiler/src/lib.rs @@ -0,0 +1,12 @@ +//! HypnoScript Compiler and Interpreter +//! +//! This module provides the compiler infrastructure and interpreter for HypnoScript. + +pub mod interpreter; +pub mod type_checker; +pub mod wasm_codegen; + +// Re-export commonly used types +pub use interpreter::{Interpreter, InterpreterError, Value}; +pub use type_checker::TypeChecker; +pub use wasm_codegen::WasmCodeGenerator; diff --git a/hypnoscript-compiler/src/type_checker.rs b/hypnoscript-compiler/src/type_checker.rs new file mode 100644 index 0000000..4c5f544 --- /dev/null +++ b/hypnoscript-compiler/src/type_checker.rs @@ -0,0 +1,1682 @@ +use hypnoscript_core::{HypnoBaseType, HypnoType}; +use hypnoscript_lexer_parser::ast::{ + AstNode, SessionField, SessionMember, SessionMethod, SessionVisibility, +}; +use std::collections::HashMap; + +#[derive(Debug, Clone)] +struct SessionFieldInfo { + ty: HypnoType, + visibility: SessionVisibility, + is_static: bool, +} + +#[derive(Debug, Clone)] +struct SessionMethodInfo { + parameter_types: Vec, + return_type: HypnoType, + visibility: SessionVisibility, + is_static: bool, + is_constructor: bool, +} + +#[derive(Debug, Clone)] +struct SessionInfo { + name: String, + instance_fields: HashMap, + static_fields: HashMap, + instance_methods: HashMap, + static_methods: HashMap, + constructor: Option, +} + +impl SessionInfo { + fn new(name: String) -> Self { + Self { + name, + instance_fields: HashMap::new(), + static_fields: HashMap::new(), + instance_methods: HashMap::new(), + static_methods: HashMap::new(), + constructor: None, + } + } +} + +/// Type checker for HypnoScript programs +pub struct TypeChecker { + // Type environment for variables + type_env: HashMap, + // Function signatures + function_types: HashMap, HypnoType)>, + // Current function return type (for return statement checking) + current_function_return_type: Option, + // Session metadata cache + sessions: HashMap, + // Currently checked session context (if any) + current_session: Option, + // Indicates whether we are inside a static method scope + in_static_context: bool, + // Error messages + errors: Vec, +} + +impl Default for TypeChecker { + fn default() -> Self { + Self::new() + } +} + +impl TypeChecker { + /// Create a new type checker + pub fn new() -> Self { + let mut checker = Self { + type_env: HashMap::new(), + function_types: HashMap::new(), + current_function_return_type: None, + sessions: HashMap::new(), + current_session: None, + in_static_context: false, + errors: Vec::new(), + }; + + // Register builtin functions + checker.register_builtins(); + + checker + } + + /// Register builtin function signatures + fn register_builtins(&mut self) { + // Math + for name in [ + "Sin", "Cos", "Tan", "Sqrt", "Log", "Log10", "Abs", "Floor", "Ceil", "Round", + ] { + self.register_builtin(name, vec![HypnoType::number()], HypnoType::number()); + } + for name in ["Min", "Max", "Pow"] { + self.register_builtin( + name, + vec![HypnoType::number(), HypnoType::number()], + HypnoType::number(), + ); + } + for name in ["Factorial", "Gcd", "Lcm", "Fibonacci"] { + self.register_builtin(name, vec![HypnoType::number()], HypnoType::number()); + } + self.register_builtin("IsPrime", vec![HypnoType::number()], HypnoType::boolean()); + self.register_builtin( + "Clamp", + vec![ + HypnoType::number(), + HypnoType::number(), + HypnoType::number(), + ], + HypnoType::number(), + ); + + // Strings + self.register_builtin("Length", vec![HypnoType::string()], HypnoType::number()); + for name in [ + "ToUpper", + "ToLower", + "Trim", + "Reverse", + "Capitalize", + "RemoveDuplicates", + "UniqueCharacters", + "ReverseWords", + "TitleCase", + ] { + self.register_builtin(name, vec![HypnoType::string()], HypnoType::string()); + } + self.register_builtin( + "IndexOf", + vec![HypnoType::string(), HypnoType::string()], + HypnoType::number(), + ); + self.register_builtin( + "Replace", + vec![ + HypnoType::string(), + HypnoType::string(), + HypnoType::string(), + ], + HypnoType::string(), + ); + self.register_builtin( + "StartsWith", + vec![HypnoType::string(), HypnoType::string()], + HypnoType::boolean(), + ); + self.register_builtin( + "EndsWith", + vec![HypnoType::string(), HypnoType::string()], + HypnoType::boolean(), + ); + self.register_builtin( + "Contains", + vec![HypnoType::string(), HypnoType::string()], + HypnoType::boolean(), + ); + self.register_builtin( + "Split", + vec![HypnoType::string(), HypnoType::string()], + HypnoType::create_array(HypnoType::string()), + ); + self.register_builtin( + "Substring", + vec![ + HypnoType::string(), + HypnoType::number(), + HypnoType::number(), + ], + HypnoType::string(), + ); + self.register_builtin( + "Repeat", + vec![HypnoType::string(), HypnoType::number()], + HypnoType::string(), + ); + for name in ["PadLeft", "PadRight"] { + self.register_builtin( + name, + vec![ + HypnoType::string(), + HypnoType::number(), + HypnoType::string(), + ], + HypnoType::string(), + ); + } + self.register_builtin("IsEmpty", vec![HypnoType::string()], HypnoType::boolean()); + self.register_builtin( + "IsWhitespace", + vec![HypnoType::string()], + HypnoType::boolean(), + ); + + // Arrays + let any_array = || HypnoType::create_array(HypnoType::unknown()); + let number_array = || HypnoType::create_array(HypnoType::number()); + let string_array = || HypnoType::create_array(HypnoType::string()); + + self.register_builtin("ArrayLength", vec![any_array()], HypnoType::number()); + self.register_builtin("ArrayIsEmpty", vec![any_array()], HypnoType::boolean()); + self.register_builtin( + "ArrayGet", + vec![any_array(), HypnoType::number()], + HypnoType::unknown(), + ); + self.register_builtin( + "ArrayIndexOf", + vec![any_array(), HypnoType::unknown()], + HypnoType::number(), + ); + self.register_builtin( + "ArrayContains", + vec![any_array(), HypnoType::unknown()], + HypnoType::boolean(), + ); + self.register_builtin("ArrayReverse", vec![any_array()], any_array()); + for name in ["ArraySum", "ArrayAverage", "ArrayMin", "ArrayMax"] { + self.register_builtin(name, vec![number_array()], HypnoType::number()); + } + self.register_builtin("ArraySort", vec![number_array()], number_array()); + for name in ["ArrayFirst", "ArrayLast"] { + self.register_builtin(name, vec![any_array()], HypnoType::unknown()); + } + for name in ["ArrayTake", "ArraySkip"] { + self.register_builtin(name, vec![any_array(), HypnoType::number()], any_array()); + } + self.register_builtin( + "ArraySlice", + vec![any_array(), HypnoType::number(), HypnoType::number()], + any_array(), + ); + self.register_builtin( + "ArrayJoin", + vec![any_array(), HypnoType::string()], + HypnoType::string(), + ); + self.register_builtin( + "ArrayCount", + vec![any_array(), HypnoType::unknown()], + HypnoType::number(), + ); + self.register_builtin("ArrayDistinct", vec![any_array()], any_array()); + + // Core / Hypnotic + self.register_builtin("Observe", vec![HypnoType::unknown()], HypnoType::unknown()); + for name in ["Drift", "DeepTrance", "HypnoticCountdown"] { + self.register_builtin(name, vec![HypnoType::number()], HypnoType::unknown()); + } + self.register_builtin( + "TranceInduction", + vec![HypnoType::string()], + HypnoType::unknown(), + ); + self.register_builtin( + "HypnoticVisualization", + vec![HypnoType::string()], + HypnoType::unknown(), + ); + self.register_builtin("ToInt", vec![HypnoType::number()], HypnoType::number()); + self.register_builtin("ToDouble", vec![HypnoType::string()], HypnoType::number()); + self.register_builtin("ToString", vec![HypnoType::unknown()], HypnoType::string()); + self.register_builtin("ToBoolean", vec![HypnoType::string()], HypnoType::boolean()); + + // File / IO + self.register_builtin("ReadFile", vec![HypnoType::string()], HypnoType::string()); + for name in ["WriteFile", "AppendFile"] { + self.register_builtin( + name, + vec![HypnoType::string(), HypnoType::string()], + HypnoType::unknown(), + ); + } + for name in ["DeleteFile", "CreateDirectory"] { + self.register_builtin(name, vec![HypnoType::string()], HypnoType::unknown()); + } + for name in ["FileExists", "IsFile", "IsDirectory"] { + self.register_builtin(name, vec![HypnoType::string()], HypnoType::boolean()); + } + self.register_builtin("ListDirectory", vec![HypnoType::string()], string_array()); + self.register_builtin( + "GetFileSize", + vec![HypnoType::string()], + HypnoType::number(), + ); + self.register_builtin( + "CopyFile", + vec![HypnoType::string(), HypnoType::string()], + HypnoType::number(), + ); + self.register_builtin( + "RenameFile", + vec![HypnoType::string(), HypnoType::string()], + HypnoType::unknown(), + ); + for name in ["GetFileExtension", "GetFileName", "GetParentDirectory"] { + self.register_builtin(name, vec![HypnoType::string()], HypnoType::string()); + } + + // Hashing / Utility + self.register_builtin("HashString", vec![HypnoType::string()], HypnoType::number()); + self.register_builtin("HashNumber", vec![HypnoType::number()], HypnoType::number()); + self.register_builtin( + "SimpleRandom", + vec![HypnoType::number()], + HypnoType::number(), + ); + self.register_builtin( + "AreAnagrams", + vec![HypnoType::string(), HypnoType::string()], + HypnoType::boolean(), + ); + self.register_builtin( + "IsPalindrome", + vec![HypnoType::string()], + HypnoType::boolean(), + ); + self.register_builtin( + "CountOccurrences", + vec![HypnoType::string(), HypnoType::string()], + HypnoType::number(), + ); + + // Statistics + for name in [ + "Mean", + "Median", + "Mode", + "StandardDeviation", + "Variance", + "Range", + ] { + self.register_builtin(name, vec![number_array()], HypnoType::number()); + } + self.register_builtin( + "Percentile", + vec![number_array(), HypnoType::number()], + HypnoType::number(), + ); + self.register_builtin( + "Correlation", + vec![number_array(), number_array()], + HypnoType::number(), + ); + self.register_builtin( + "LinearRegression", + vec![number_array(), number_array()], + number_array(), + ); + + // System + self.register_builtin("GetCurrentDirectory", vec![], HypnoType::string()); + self.register_builtin("GetEnv", vec![HypnoType::string()], HypnoType::string()); + self.register_builtin( + "SetEnv", + vec![HypnoType::string(), HypnoType::string()], + HypnoType::unknown(), + ); + self.register_builtin("GetOperatingSystem", vec![], HypnoType::string()); + self.register_builtin("GetArchitecture", vec![], HypnoType::string()); + self.register_builtin("GetCpuCount", vec![], HypnoType::number()); + self.register_builtin("GetHostname", vec![], HypnoType::string()); + self.register_builtin("GetUsername", vec![], HypnoType::string()); + self.register_builtin("GetHomeDirectory", vec![], HypnoType::string()); + self.register_builtin("GetTempDirectory", vec![], HypnoType::string()); + self.register_builtin("GetArgs", vec![], string_array()); + self.register_builtin("Exit", vec![HypnoType::number()], HypnoType::unknown()); + + // Time / Date + self.register_builtin("CurrentTimestamp", vec![], HypnoType::number()); + self.register_builtin("CurrentDate", vec![], HypnoType::string()); + self.register_builtin("CurrentTime", vec![], HypnoType::string()); + self.register_builtin("CurrentDateTime", vec![], HypnoType::string()); + self.register_builtin( + "FormatDateTime", + vec![HypnoType::string()], + HypnoType::string(), + ); + self.register_builtin("DayOfWeek", vec![], HypnoType::number()); + self.register_builtin("DayOfYear", vec![], HypnoType::number()); + self.register_builtin( + "IsLeapYear", + vec![HypnoType::number()], + HypnoType::boolean(), + ); + self.register_builtin( + "DaysInMonth", + vec![HypnoType::number(), HypnoType::number()], + HypnoType::number(), + ); + self.register_builtin("CurrentYear", vec![], HypnoType::number()); + self.register_builtin("CurrentMonth", vec![], HypnoType::number()); + self.register_builtin("CurrentDay", vec![], HypnoType::number()); + self.register_builtin("CurrentHour", vec![], HypnoType::number()); + self.register_builtin("CurrentMinute", vec![], HypnoType::number()); + self.register_builtin("CurrentSecond", vec![], HypnoType::number()); + + // Validation + for name in [ + "IsValidEmail", + "IsValidUrl", + "IsValidPhoneNumber", + "IsAlphanumeric", + "IsAlphabetic", + "IsNumeric", + "IsLowercase", + "IsUppercase", + ] { + self.register_builtin(name, vec![HypnoType::string()], HypnoType::boolean()); + } + self.register_builtin( + "IsInRange", + vec![ + HypnoType::number(), + HypnoType::number(), + HypnoType::number(), + ], + HypnoType::boolean(), + ); + self.register_builtin( + "MatchesPattern", + vec![HypnoType::string(), HypnoType::string()], + HypnoType::boolean(), + ); + } + + fn register_builtin( + &mut self, + name: &str, + parameter_types: Vec, + return_type: HypnoType, + ) { + self.function_types + .insert(name.to_string(), (parameter_types, return_type)); + } + + /// Parse type annotation string to HypnoType + fn parse_type_annotation(&self, type_str: Option<&str>) -> HypnoType { + match type_str { + Some("number") => HypnoType::number(), + Some("string") => HypnoType::string(), + Some("boolean") => HypnoType::boolean(), + Some("trance") => HypnoType::new(HypnoBaseType::Trance, None), + _ => HypnoType::unknown(), + } + } + + /// Check a program and return errors + pub fn check_program(&mut self, program: &AstNode) -> Vec { + self.errors.clear(); + + if let AstNode::Program(statements) = program { + // Collect session metadata before type evaluation + for stmt in statements { + self.collect_session_signature(stmt); + } + + // First pass: collect function declarations + for stmt in statements { + self.collect_function_signature(stmt); + } + + // Second pass: type check all statements + for stmt in statements { + self.check_statement(stmt); + } + } else { + self.errors.push("Expected program node".to_string()); + } + + self.errors.clone() + } + + /// Collect function signatures (including triggers) + fn collect_function_signature(&mut self, stmt: &AstNode) { + match stmt { + AstNode::FunctionDeclaration { + name, + parameters, + return_type, + .. + } + | AstNode::TriggerDeclaration { + name, + parameters, + return_type, + .. + } => { + let param_types: Vec = parameters + .iter() + .map(|p| self.parse_type_annotation(p.type_annotation.as_deref())) + .collect(); + + let ret_type = self.parse_type_annotation(return_type.as_deref()); + + self.function_types + .insert(name.clone(), (param_types, ret_type)); + } + _ => {} + } + } + + fn collect_session_signature(&mut self, stmt: &AstNode) { + let AstNode::SessionDeclaration { name, members } = stmt else { + return; + }; + + if self.sessions.contains_key(name) { + self.errors + .push(format!("Duplicate session declaration '{}'", name)); + return; + } + + let mut info = SessionInfo::new(name.clone()); + + for member in members { + match member { + SessionMember::Field(field) => { + let field_type = self.parse_type_annotation(field.type_annotation.as_deref()); + let field_info = SessionFieldInfo { + ty: field_type, + visibility: field.visibility, + is_static: field.is_static, + }; + + let map = if field.is_static { + &mut info.static_fields + } else { + &mut info.instance_fields + }; + + if map.contains_key(&field.name) { + self.errors.push(format!( + "Duplicate field '{}' in session '{}'", + field.name, name + )); + } else { + map.insert(field.name.clone(), field_info); + } + } + SessionMember::Method(method) => { + let method_info = self.build_method_info(name, method); + + match method_info { + Ok(info_item) => { + if info_item.is_constructor { + if info.constructor.is_some() { + self.errors.push(format!( + "Multiple constructors defined for session '{}'", + name + )); + } else { + info.constructor = Some(info_item); + } + continue; + } + + let target_map = if info_item.is_static { + &mut info.static_methods + } else { + &mut info.instance_methods + }; + + if target_map.contains_key(&method.name) { + self.errors.push(format!( + "Duplicate method '{}' in session '{}'", + method.name, name + )); + } else { + target_map.insert(method.name.clone(), info_item); + } + } + Err(err) => { + self.errors.push(err); + } + } + } + } + } + + // Ensure constructor signature is registered as callable for session instantiation + if let Some(constructor) = info.constructor.as_ref() { + self.function_types.insert( + name.clone(), + ( + constructor.parameter_types.clone(), + self.make_session_instance_type(name), + ), + ); + } else { + // Sessions without explicit constructor accept zero arguments + self.function_types.insert( + name.clone(), + (Vec::new(), self.make_session_instance_type(name)), + ); + } + + self.sessions.insert(name.clone(), info); + self.type_env + .insert(name.clone(), self.make_session_type(name)); + } + + fn build_method_info( + &self, + session_name: &str, + method: &SessionMethod, + ) -> Result { + if method.is_constructor && method.is_static { + return Err(format!( + "Constructor in session '{}' cannot be static", + session_name + )); + } + + let parameter_types = method + .parameters + .iter() + .map(|param| self.parse_type_annotation(param.type_annotation.as_deref())) + .collect(); + + let return_type = if method.is_constructor { + self.make_session_instance_type(session_name) + } else { + self.parse_type_annotation(method.return_type.as_deref()) + }; + + Ok(SessionMethodInfo { + parameter_types, + return_type, + visibility: method.visibility, + is_static: method.is_static, + is_constructor: method.is_constructor, + }) + } + + fn make_session_type(&self, name: &str) -> HypnoType { + HypnoType::new(HypnoBaseType::Session, Some(format!("{}::type", name))) + } + + fn make_session_instance_type(&self, name: &str) -> HypnoType { + HypnoType::new(HypnoBaseType::Session, Some(name.to_string())) + } + + fn check_session_field(&mut self, session_name: &str, field: &SessionField) { + let prev_static = self.in_static_context; + self.in_static_context = field.is_static; + + let expected_type = self.parse_type_annotation(field.type_annotation.as_deref()); + if let Some(initializer) = field.initializer.as_ref() { + let actual_type = self.infer_type(initializer); + if !self.types_compatible(&expected_type, &actual_type) { + self.errors.push(format!( + "Field '{}' in session '{}' expects type {}, got {}", + field.name, session_name, expected_type, actual_type + )); + } + } + + self.in_static_context = prev_static; + } + + fn check_session_method(&mut self, session_name: &str, method: &SessionMethod) { + let saved_env = self.type_env.clone(); + let saved_return = self.current_function_return_type.clone(); + let saved_static = self.in_static_context; + + self.in_static_context = method.is_static; + + let return_type = if method.is_constructor { + self.make_session_instance_type(session_name) + } else { + self.parse_type_annotation(method.return_type.as_deref()) + }; + self.current_function_return_type = Some(return_type); + + if !method.is_static { + self.type_env.insert( + "this".to_string(), + self.make_session_instance_type(session_name), + ); + } + + for param in &method.parameters { + let param_type = self.parse_type_annotation(param.type_annotation.as_deref()); + self.type_env.insert(param.name.clone(), param_type); + } + + for stmt in &method.body { + self.check_statement(stmt); + } + + self.type_env = saved_env; + self.current_function_return_type = saved_return; + self.in_static_context = saved_static; + } + + fn session_lookup(&self, ty: &HypnoType) -> Option<(SessionInfo, bool)> { + if ty.base_type != HypnoBaseType::Session { + return None; + } + + let name = ty.name.as_deref()?; + if let Some(stripped) = name.strip_suffix("::type") { + self.sessions + .get(stripped) + .cloned() + .map(|info| (info, true)) + } else { + self.sessions.get(name).cloned().map(|info| (info, false)) + } + } + + fn visibility_allows(&self, session_name: &str, visibility: SessionVisibility) -> bool { + visibility == SessionVisibility::Public + || self + .current_session + .as_deref() + .is_some_and(|current| current == session_name) + } + + fn method_function_type(&self, method: &SessionMethodInfo) -> HypnoType { + HypnoType::create_function(method.parameter_types.clone(), method.return_type.clone()) + } + + fn infer_session_member(&mut self, object: &AstNode, property: &str) -> HypnoType { + let object_type = self.infer_type(object); + let Some((session_info, is_static_reference)) = self.session_lookup(&object_type) else { + self.errors.push(format!( + "Cannot access member '{}' on value of type {}", + property, object_type + )); + return HypnoType::unknown(); + }; + + let session_name = session_info.name.clone(); + + if is_static_reference { + if let Some(field) = session_info.static_fields.get(property).cloned() { + debug_assert!(field.is_static); + if !self.visibility_allows(&session_name, field.visibility) { + self.errors.push(format!( + "Static field '{}' of session '{}' is not visible here", + property, session_name + )); + return HypnoType::unknown(); + } + return field.ty; + } + + if session_info.instance_fields.contains_key(property) { + self.errors.push(format!( + "Cannot access instance field '{}' on session type '{}'", + property, session_name + )); + return HypnoType::unknown(); + } + + if let Some(method) = session_info.static_methods.get(property).cloned() { + if !self.visibility_allows(&session_name, method.visibility) { + self.errors.push(format!( + "Static method '{}' of session '{}' is not visible here", + property, session_name + )); + return HypnoType::unknown(); + } + return self.method_function_type(&method); + } + + if session_info.instance_methods.contains_key(property) { + self.errors.push(format!( + "Cannot access instance method '{}' on session type '{}'", + property, session_name + )); + return HypnoType::unknown(); + } + + self.errors.push(format!( + "Session '{}' has no static member '{}'", + session_name, property + )); + return HypnoType::unknown(); + } + + if let Some(field) = session_info.instance_fields.get(property).cloned() { + debug_assert!(!field.is_static); + if !self.visibility_allows(&session_name, field.visibility) { + self.errors.push(format!( + "Field '{}' of session '{}' is not visible here", + property, session_name + )); + return HypnoType::unknown(); + } + return field.ty; + } + + if let Some(field) = session_info.static_fields.get(property).cloned() { + debug_assert!(field.is_static); + if !self.visibility_allows(&session_name, field.visibility) { + self.errors.push(format!( + "Static field '{}' of session '{}' is not visible here", + property, session_name + )); + return HypnoType::unknown(); + } + return field.ty; + } + + if let Some(method) = session_info.instance_methods.get(property).cloned() { + if !self.visibility_allows(&session_name, method.visibility) { + self.errors.push(format!( + "Method '{}' of session '{}' is not visible here", + property, session_name + )); + return HypnoType::unknown(); + } + return self.method_function_type(&method); + } + + if let Some(method) = session_info.static_methods.get(property).cloned() { + if !self.visibility_allows(&session_name, method.visibility) { + self.errors.push(format!( + "Static method '{}' of session '{}' is not visible here", + property, session_name + )); + return HypnoType::unknown(); + } + return self.method_function_type(&method); + } + + self.errors.push(format!( + "Session '{}' has no member '{}'", + session_name, property + )); + HypnoType::unknown() + } + + fn check_session_method_call( + &mut self, + object: &AstNode, + property: &str, + arguments: &[AstNode], + ) -> HypnoType { + let object_type = self.infer_type(object); + let Some((session_info, is_static_reference)) = self.session_lookup(&object_type) else { + self.errors.push(format!( + "Cannot call member '{}' on value of type {}", + property, object_type + )); + return HypnoType::unknown(); + }; + + let session_name = session_info.name.clone(); + let instance_method = session_info.instance_methods.get(property).cloned(); + let static_method = session_info.static_methods.get(property).cloned(); + + let method = if is_static_reference { + if instance_method.is_some() { + self.errors.push(format!( + "Cannot call instance method '{}' on session type '{}'", + property, session_name + )); + return HypnoType::unknown(); + } + static_method + } else { + instance_method.or(static_method) + }; + + if let Some(method_info) = method { + if !self.visibility_allows(&session_name, method_info.visibility) { + self.errors.push(format!( + "Method '{}' of session '{}' is not visible here", + property, session_name + )); + return HypnoType::unknown(); + } + + if method_info.is_constructor { + self.errors.push(format!( + "Constructor '{}' of session '{}' cannot be invoked as a member", + property, session_name + )); + return HypnoType::unknown(); + } + + if is_static_reference && !method_info.is_static { + self.errors.push(format!( + "Cannot call instance method '{}' on session type '{}'", + property, session_name + )); + return HypnoType::unknown(); + } + + if arguments.len() != method_info.parameter_types.len() { + self.errors.push(format!( + "Method '{}' of session '{}' expects {} arguments, got {}", + property, + session_name, + method_info.parameter_types.len(), + arguments.len() + )); + } else { + for (idx, (arg, expected)) in arguments + .iter() + .zip(method_info.parameter_types.iter()) + .enumerate() + { + let actual = self.infer_type(arg); + if !self.types_compatible(expected, &actual) { + self.errors.push(format!( + "Method '{}' argument {} type mismatch: expected {}, got {}", + property, + idx + 1, + expected, + actual + )); + } + } + } + + return method_info.return_type.clone(); + } + + if session_info.instance_fields.contains_key(property) { + self.errors.push(format!( + "Member '{}' of session '{}' is a field and cannot be called", + property, session_name + )); + } else if session_info.static_fields.contains_key(property) { + if is_static_reference { + self.errors.push(format!( + "Static field '{}' of session '{}' cannot be called", + property, session_name + )); + } else { + self.errors.push(format!( + "Field '{}' of session '{}' cannot be called", + property, session_name + )); + } + } else if is_static_reference { + self.errors.push(format!( + "Session '{}' has no static method '{}'", + session_name, property + )); + } else { + self.errors.push(format!( + "Session '{}' has no method '{}'", + session_name, property + )); + } + + HypnoType::unknown() + } + + fn check_member_assignment( + &mut self, + object: &AstNode, + property: &str, + value: &AstNode, + ) -> HypnoType { + let object_type = self.infer_type(object); + let Some((session_info, is_static_reference)) = self.session_lookup(&object_type) else { + self.errors.push(format!( + "Assignment target '{}' is not a session member (type: {})", + property, object_type + )); + return HypnoType::unknown(); + }; + + let session_name = session_info.name.clone(); + let instance_field = session_info.instance_fields.get(property).cloned(); + let static_field = session_info.static_fields.get(property).cloned(); + + if is_static_reference { + if let Some(field) = static_field { + debug_assert!(field.is_static); + if !self.visibility_allows(&session_name, field.visibility) { + self.errors.push(format!( + "Static field '{}' of session '{}' is not visible here", + property, session_name + )); + return HypnoType::unknown(); + } + + let value_type = self.infer_type(value); + if !self.types_compatible(&field.ty, &value_type) { + self.errors.push(format!( + "Cannot assign value of type {} to static field '{}' of session '{}' (expected {})", + value_type, property, session_name, field.ty + )); + } + return field.ty; + } + + if instance_field.is_some() { + self.errors.push(format!( + "Cannot assign to instance field '{}' on session type '{}'", + property, session_name + )); + return HypnoType::unknown(); + } + + if session_info.static_methods.contains_key(property) + || session_info.instance_methods.contains_key(property) + { + self.errors.push(format!( + "Cannot assign to method '{}' of session '{}'", + property, session_name + )); + return HypnoType::unknown(); + } + + self.errors.push(format!( + "Session '{}' has no static field '{}'", + session_name, property + )); + return HypnoType::unknown(); + } + + if let Some(field) = instance_field { + debug_assert!(!field.is_static); + if !self.visibility_allows(&session_name, field.visibility) { + self.errors.push(format!( + "Field '{}' of session '{}' is not visible here", + property, session_name + )); + return HypnoType::unknown(); + } + + let value_type = self.infer_type(value); + if !self.types_compatible(&field.ty, &value_type) { + self.errors.push(format!( + "Cannot assign value of type {} to field '{}' of session '{}' (expected {})", + value_type, property, session_name, field.ty + )); + } + + return field.ty; + } + + if let Some(field) = static_field { + debug_assert!(field.is_static); + if !self.visibility_allows(&session_name, field.visibility) { + self.errors.push(format!( + "Static field '{}' of session '{}' is not visible here", + property, session_name + )); + return HypnoType::unknown(); + } + + self.errors.push(format!( + "Assign static field '{}' through session '{}', not an instance", + property, session_name + )); + return HypnoType::unknown(); + } + + if session_info.instance_methods.contains_key(property) + || session_info.static_methods.contains_key(property) + { + self.errors.push(format!( + "Cannot assign to method '{}' of session '{}'", + property, session_name + )); + return HypnoType::unknown(); + } + + self.errors.push(format!( + "Session '{}' has no field '{}'", + session_name, property + )); + HypnoType::unknown() + } + + /// Check a statement + fn check_statement(&mut self, stmt: &AstNode) { + match stmt { + AstNode::VariableDeclaration { + name, + type_annotation, + initializer, + is_constant, + } => { + let expected_type = self.parse_type_annotation(type_annotation.as_deref()); + + if let Some(init) = initializer { + let actual_type = self.infer_type(init); + + if !self.types_compatible(&expected_type, &actual_type) { + self.errors.push(format!( + "Type mismatch for variable '{}': expected {}, got {}", + name, expected_type, actual_type + )); + } + } else if *is_constant { + self.errors + .push(format!("Constant variable '{}' must be initialized", name)); + } + + self.type_env.insert(name.clone(), expected_type); + } + + AstNode::AnchorDeclaration { name, source } => { + let source_type = self.infer_type(source); + self.type_env.insert(name.clone(), source_type); + } + + AstNode::FunctionDeclaration { + parameters, + return_type, + body, + .. + } => { + let old_env = self.type_env.clone(); + let ret_type = self.parse_type_annotation(return_type.as_deref()); + self.current_function_return_type = Some(ret_type); + + for param in parameters { + let param_type = self.parse_type_annotation(param.type_annotation.as_deref()); + self.type_env.insert(param.name.clone(), param_type); + } + + for stmt in body { + self.check_statement(stmt); + } + + self.type_env = old_env; + self.current_function_return_type = None; + } + + AstNode::TriggerDeclaration { + parameters, + return_type, + body, + .. + } => { + // Triggers are handled like functions + let old_env = self.type_env.clone(); + let ret_type = self.parse_type_annotation(return_type.as_deref()); + self.current_function_return_type = Some(ret_type); + + for param in parameters { + let param_type = self.parse_type_annotation(param.type_annotation.as_deref()); + self.type_env.insert(param.name.clone(), param_type); + } + + for stmt in body { + self.check_statement(stmt); + } + + self.type_env = old_env; + self.current_function_return_type = None; + } + + AstNode::EntranceBlock(statements) | AstNode::FinaleBlock(statements) => { + for stmt in statements { + self.check_statement(stmt); + } + } + + AstNode::IfStatement { + condition, + then_branch, + else_branch, + } => { + let cond_type = self.infer_type(condition); + if cond_type.base_type != HypnoBaseType::Boolean { + self.errors + .push(format!("If condition must be boolean, got {}", cond_type)); + } + + for stmt in then_branch { + self.check_statement(stmt); + } + + if let Some(else_stmts) = else_branch { + for stmt in else_stmts { + self.check_statement(stmt); + } + } + } + + AstNode::DeepFocusStatement { condition, body } => { + let cond_type = self.infer_type(condition); + if cond_type.base_type != HypnoBaseType::Boolean { + self.errors.push(format!( + "DeepFocus condition must be boolean, got {}", + cond_type + )); + } + + for stmt in body { + self.check_statement(stmt); + } + } + + AstNode::WhileStatement { condition, body } => { + let cond_type = self.infer_type(condition); + if cond_type.base_type != HypnoBaseType::Boolean { + self.errors.push(format!( + "While condition must be boolean, got {}", + cond_type + )); + } + + for stmt in body { + self.check_statement(stmt); + } + } + + AstNode::LoopStatement { body } => { + for stmt in body { + self.check_statement(stmt); + } + } + + AstNode::OscillateStatement { target } => { + let target_type = self.infer_type(target); + if target_type.base_type != HypnoBaseType::Boolean { + self.errors.push(format!( + "Oscillate target must be boolean, got {}", + target_type + )); + } + } + + AstNode::SessionDeclaration { name, members } => { + let prev_session = self.current_session.clone(); + let prev_static = self.in_static_context; + + self.current_session = Some(name.clone()); + self.in_static_context = false; + + for member in members { + match member { + SessionMember::Field(field) => self.check_session_field(name, field), + SessionMember::Method(method) => self.check_session_method(name, method), + } + } + + self.current_session = prev_session; + self.in_static_context = prev_static; + } + + #[allow(clippy::collapsible_match)] + AstNode::ReturnStatement(value) => { + if let Some(val) = value { + let actual_type = self.infer_type(val); + if let Some(ret_type) = &self.current_function_return_type.clone() { + if !self.types_compatible(ret_type, &actual_type) { + self.errors.push(format!( + "Return type mismatch: expected {}, got {}", + ret_type, actual_type + )); + } + } + } + } + + AstNode::ExpressionStatement(expr) + | AstNode::ObserveStatement(expr) + | AstNode::WhisperStatement(expr) + | AstNode::CommandStatement(expr) => { + self.infer_type(expr); + } + + _ => {} + } + } + + /// Infer the type of an expression + fn infer_type(&mut self, expr: &AstNode) -> HypnoType { + match expr { + AstNode::NumberLiteral(_) => HypnoType::number(), + AstNode::StringLiteral(_) => HypnoType::string(), + AstNode::BooleanLiteral(_) => HypnoType::boolean(), + + AstNode::Identifier(name) => { + if name == "this" && self.in_static_context { + self.errors + .push("Cannot use 'this' in a static context".to_string()); + return HypnoType::unknown(); + } + + self.type_env.get(name).cloned().unwrap_or_else(|| { + self.errors.push(format!("Undefined variable '{}'", name)); + HypnoType::unknown() + }) + } + + AstNode::BinaryExpression { + left, + operator, + right, + } => { + let left_type = self.infer_type(left); + let right_type = self.infer_type(right); + let normalized_op = operator.to_ascii_lowercase(); + + match normalized_op.as_str() { + "+" | "-" | "*" | "/" | "%" => { + if left_type.base_type != HypnoBaseType::Number + || right_type.base_type != HypnoBaseType::Number + { + self.errors.push(format!( + "Arithmetic operator '{}' requires numeric operands, got {} and {}", + operator, left_type, right_type + )); + } + HypnoType::number() + } + "==" | "!=" | "youarefeelingverysleepy" | "youcannotresist" | "notsodeep" => { + HypnoType::boolean() + } + ">" + | "<" + | ">=" + | "<=" + | "lookatthewatch" + | "fallundermyspell" + | "youreyesaregettingheavy" + | "goingdeeper" + | "deeplygreater" + | "deeplyless" => { + if left_type.base_type != HypnoBaseType::Number + || right_type.base_type != HypnoBaseType::Number + { + self.errors.push(format!( + "Comparison operator '{}' requires numeric operands, got {} and {}", + operator, left_type, right_type + )); + } + HypnoType::boolean() + } + "&&" | "undermycontrol" | "||" | "resistanceisfutile" => { + if left_type.base_type != HypnoBaseType::Boolean + || right_type.base_type != HypnoBaseType::Boolean + { + self.errors.push(format!( + "Logical operator '{}' requires boolean operands, got {} and {}", + operator, left_type, right_type + )); + } + HypnoType::boolean() + } + _ => HypnoType::unknown(), + } + } + + AstNode::UnaryExpression { operator, operand } => { + let operand_type = self.infer_type(operand); + + match operator.as_str() { + "-" => { + if operand_type.base_type != HypnoBaseType::Number { + self.errors.push(format!( + "Unary minus requires numeric operand, got {}", + operand_type + )); + } + HypnoType::number() + } + "!" => { + if operand_type.base_type != HypnoBaseType::Boolean { + self.errors.push(format!( + "Logical not requires boolean operand, got {}", + operand_type + )); + } + HypnoType::boolean() + } + _ => HypnoType::unknown(), + } + } + + AstNode::CallExpression { callee, arguments } => match callee.as_ref() { + AstNode::Identifier(func_name) => { + let func_sig = self.function_types.get(func_name).cloned(); + + if let Some((param_types, return_type)) = func_sig { + if arguments.len() != param_types.len() { + self.errors.push(format!( + "Function '{}' expects {} arguments, got {}", + func_name, + param_types.len(), + arguments.len() + )); + } else { + for (i, (arg, expected_type)) in + arguments.iter().zip(param_types.iter()).enumerate() + { + let actual_type = self.infer_type(arg); + if !self.types_compatible(expected_type, &actual_type) { + self.errors.push(format!( + "Function '{}' argument {} type mismatch: expected {}, got {}", + func_name, + i + 1, + expected_type, + actual_type + )); + } + } + } + + return_type + } else { + self.errors + .push(format!("Undefined function '{}'", func_name)); + HypnoType::unknown() + } + } + AstNode::MemberExpression { object, property } => { + self.check_session_method_call(object, property, arguments) + } + _ => { + let callee_type = self.infer_type(callee); + if callee_type.base_type != HypnoBaseType::Function { + self.errors + .push(format!("Value of type {} is not callable", callee_type)); + return HypnoType::unknown(); + } + + let param_types = callee_type.parameter_types.clone().unwrap_or_default(); + let return_type = callee_type + .return_type + .clone() + .map(|boxed| (*boxed).clone()) + .unwrap_or_else(HypnoType::unknown); + + if arguments.len() != param_types.len() { + self.errors.push(format!( + "Callable expects {} arguments, got {}", + param_types.len(), + arguments.len() + )); + } else { + for (i, (arg, expected_type)) in + arguments.iter().zip(param_types.iter()).enumerate() + { + let actual_type = self.infer_type(arg); + if !self.types_compatible(expected_type, &actual_type) { + self.errors.push(format!( + "Callable argument {} type mismatch: expected {}, got {}", + i + 1, + expected_type, + actual_type + )); + } + } + } + + return_type + } + }, + + AstNode::MemberExpression { object, property } => { + self.infer_session_member(object, property) + } + + AstNode::AssignmentExpression { target, value } => match target.as_ref() { + AstNode::Identifier(name) => { + let value_type = self.infer_type(value); + if let Some(expected_type) = self.type_env.get(name).cloned() { + if !self.types_compatible(&expected_type, &value_type) { + self.errors.push(format!( + "Cannot assign value of type {} to variable '{}' of type {}", + value_type, name, expected_type + )); + } + expected_type + } else { + self.errors + .push(format!("Cannot assign to undefined variable '{}'", name)); + HypnoType::unknown() + } + } + AstNode::MemberExpression { object, property } => { + self.check_member_assignment(object, property, value) + } + _ => { + self.errors.push("Invalid assignment target".to_string()); + HypnoType::unknown() + } + }, + + AstNode::ArrayLiteral(elements) => { + if elements.is_empty() { + HypnoType::create_array(HypnoType::unknown()) + } else { + let first_type = self.infer_type(&elements[0]); + for elem in &elements[1..] { + let elem_type = self.infer_type(elem); + if !self.types_compatible(&first_type, &elem_type) { + self.errors.push(format!( + "Array elements must have same type, got {} and {}", + first_type, elem_type + )); + } + } + HypnoType::create_array(first_type) + } + } + + _ => HypnoType::unknown(), + } + } + + /// Check if two types are compatible + fn types_compatible(&self, expected: &HypnoType, actual: &HypnoType) -> bool { + if expected.base_type == HypnoBaseType::Unknown + || actual.base_type == HypnoBaseType::Unknown + { + return true; + } + expected.is_compatible_with(actual) + } + + /// Get all errors + pub fn get_errors(&self) -> &[String] { + &self.errors + } + + /// Check if there are any errors + pub fn has_errors(&self) -> bool { + !self.errors.is_empty() + } +} + +#[cfg(test)] +mod tests { + use super::*; + use hypnoscript_lexer_parser::{Lexer, Parser}; + + #[test] + fn test_type_check_simple() { + let source = r#" +Focus { + induce x: number = 42; + induce y: number = 10; + induce sum: number = x + y; +} Relax +"#; + let mut lexer = Lexer::new(source); + let tokens = lexer.lex().unwrap(); + let mut parser = Parser::new(tokens); + let ast = parser.parse_program().unwrap(); + + let mut checker = TypeChecker::new(); + let errors = checker.check_program(&ast); + assert!(errors.is_empty(), "Errors: {:?}", errors); + } + + #[test] + fn test_operator_synonym_diagnostics() { + let source = r#" +Focus { + induce left: string = "hello"; + induce right: string = "world"; + if (left lookAtTheWatch right) { + observe "won't happen"; + } +} Relax +"#; + let mut lexer = Lexer::new(source); + let tokens = lexer.lex().unwrap(); + let mut parser = Parser::new(tokens); + let ast = parser.parse_program().unwrap(); + + let mut checker = TypeChecker::new(); + let errors = checker.check_program(&ast); + assert!( + errors.iter().any(|msg| msg.contains("lookAtTheWatch")), + "Expected comparison diagnostic mentioning operator, got {:?}", + errors + ); + } + + #[test] + fn test_type_check_private_session_member_access() { + let source = r#" +Focus { + session Account { + conceal balance: number = 0; + + expose suggestion constructor(initialBalance: number) { + this.balance = initialBalance; + } + + expose suggestion read(): number { + awaken this.balance; + } + } + + induce leaked = Account(100).balance; +} Relax +"#; + + let mut lexer = Lexer::new(source); + let tokens = lexer.lex().unwrap(); + let mut parser = Parser::new(tokens); + let ast = parser.parse_program().unwrap(); + + let mut checker = TypeChecker::new(); + let errors = checker.check_program(&ast); + assert!(!errors.is_empty()); + assert!( + errors.iter().any(|msg| { + msg.contains("Field 'balance' of session 'Account' is not visible here") + }), + "Expected private member visibility error, got {:?}", + errors + ); + } + + #[test] + fn test_type_check_static_misuse_errors() { + let source = r#" +Focus { + session Config { + expose secret: number = 42; + } + + session Env { + dominant expose name: string = "default"; + } + + induce secretValue = Config.secret; + Env().name = "prod"; +} Relax +"#; + + let mut lexer = Lexer::new(source); + let tokens = lexer.lex().unwrap(); + let mut parser = Parser::new(tokens); + let ast = parser.parse_program().unwrap(); + + let mut checker = TypeChecker::new(); + let errors = checker.check_program(&ast); + assert!( + errors.len() >= 2, + "Expected at least two errors, got {:?}", + errors + ); + assert!( + errors.iter().any(|msg| { + msg.contains("Cannot access instance field 'secret' on session type 'Config'") + }), + "Expected instance vs static access error, got {:?}", + errors + ); + assert!( + errors.iter().any(|msg| { + msg.contains("Assign static field 'name' through session 'Env', not an instance") + }), + "Expected static assignment error, got {:?}", + errors + ); + } + + #[test] + fn test_type_check_mismatch() { + let source = r#" +Focus { + induce x: number = "hello"; +} Relax +"#; + let mut lexer = Lexer::new(source); + let tokens = lexer.lex().unwrap(); + let mut parser = Parser::new(tokens); + let ast = parser.parse_program().unwrap(); + + let mut checker = TypeChecker::new(); + let errors = checker.check_program(&ast); + assert!(!errors.is_empty()); + assert!(errors[0].contains("Type mismatch")); + } +} diff --git a/hypnoscript-compiler/src/wasm_codegen.rs b/hypnoscript-compiler/src/wasm_codegen.rs new file mode 100644 index 0000000..14f5a93 --- /dev/null +++ b/hypnoscript-compiler/src/wasm_codegen.rs @@ -0,0 +1,389 @@ +use hypnoscript_lexer_parser::ast::AstNode; +use std::collections::HashMap; + +/// WASM code generator for HypnoScript +pub struct WasmCodeGenerator { + output: String, + local_counter: usize, + label_counter: usize, + variable_map: HashMap, + function_map: HashMap, + indent_level: usize, +} + +impl Default for WasmCodeGenerator { + fn default() -> Self { + Self::new() + } +} + +impl WasmCodeGenerator { + /// Create a new WASM code generator + pub fn new() -> Self { + Self { + output: String::new(), + local_counter: 0, + label_counter: 0, + variable_map: HashMap::new(), + function_map: HashMap::new(), + indent_level: 0, + } + } + + /// Generate WASM code from AST + pub fn generate(&mut self, program: &AstNode) -> String { + self.output.clear(); + self.local_counter = 0; + self.label_counter = 0; + self.variable_map.clear(); + self.function_map.clear(); + + self.emit_line("(module"); + self.indent_level += 1; + + // Emit imports + self.emit_imports(); + + // Emit memory + self.emit_line("(memory (export \"memory\") 1)"); + + // Emit global variables + self.emit_line("(global $string_offset (mut i32) (i32.const 0))"); + self.emit_line("(global $heap_offset (mut i32) (i32.const 1024))"); + + // Emit main function + if let AstNode::Program(statements) = program { + self.emit_main_function(statements); + } + + self.indent_level -= 1; + self.emit_line(")"); + + self.output.clone() + } + + /// Emit standard imports + fn emit_imports(&mut self) { + self.emit_line(";; Imports"); + self.emit_line("(import \"env\" \"console_log\" (func $console_log (param i32)))"); + self.emit_line("(import \"env\" \"console_log_f64\" (func $console_log_f64 (param f64)))"); + self.emit_line( + "(import \"env\" \"console_log_str\" (func $console_log_str (param i32 i32)))", + ); + self.emit_line("(import \"env\" \"drift\" (func $drift (param i32)))"); + self.emit_line(""); + } + + /// Emit main function + fn emit_main_function(&mut self, statements: &[AstNode]) { + self.emit_line("(func $main (export \"main\")"); + self.indent_level += 1; + + // Emit local variables + self.emit_line("(local $temp i32)"); + self.emit_line("(local $temp_f64 f64)"); + + // Emit statements + for stmt in statements { + self.emit_statement(stmt); + } + + self.indent_level -= 1; + self.emit_line(")"); + } + + /// Emit a statement + fn emit_statement(&mut self, stmt: &AstNode) { + match stmt { + AstNode::VariableDeclaration { + name, initializer, .. + } => { + let var_idx = self.local_counter; + self.variable_map.insert(name.clone(), var_idx); + self.local_counter += 1; + + // Emit local declaration at function level (would need restructuring) + if let Some(init) = initializer { + self.emit_expression(init); + self.emit_line(&format!("local.set ${}", var_idx)); + } + } + + AstNode::ObserveStatement(expr) => { + self.emit_line(";; observe statement"); + match expr.as_ref() { + AstNode::NumberLiteral(_) => { + self.emit_expression(expr); + self.emit_line("call $console_log_f64"); + } + AstNode::StringLiteral(_) => { + self.emit_expression(expr); + self.emit_line("call $console_log"); + } + _ => { + self.emit_expression(expr); + self.emit_line("call $console_log_f64"); + } + } + } + + AstNode::IfStatement { + condition, + then_branch, + else_branch, + } => { + self.emit_expression(condition); + self.emit_line("if"); + self.indent_level += 1; + + for stmt in then_branch { + self.emit_statement(stmt); + } + + if let Some(else_stmts) = else_branch { + self.indent_level -= 1; + self.emit_line("else"); + self.indent_level += 1; + + for stmt in else_stmts { + self.emit_statement(stmt); + } + } + + self.indent_level -= 1; + self.emit_line("end"); + } + + AstNode::WhileStatement { condition, body } => { + let loop_label = self.next_label(); + self.emit_line(&format!("(block ${}_end", loop_label)); + self.indent_level += 1; + self.emit_line(&format!("(loop ${}_start", loop_label)); + self.indent_level += 1; + + // Check condition + self.emit_expression(condition); + self.emit_line("i32.eqz"); + self.emit_line(&format!("br_if ${}_end", loop_label)); + + // Emit body + for stmt in body { + self.emit_statement(stmt); + } + + // Loop back + self.emit_line(&format!("br ${}_start", loop_label)); + + self.indent_level -= 1; + self.emit_line(")"); + self.indent_level -= 1; + self.emit_line(")"); + } + + AstNode::LoopStatement { body } => { + let loop_label = self.next_label(); + self.emit_line(&format!("(block ${}_end", loop_label)); + self.indent_level += 1; + self.emit_line(&format!("(loop ${}_start", loop_label)); + self.indent_level += 1; + + for stmt in body { + self.emit_statement(stmt); + } + + self.emit_line(&format!("br ${}_start", loop_label)); + + self.indent_level -= 1; + self.emit_line(")"); + self.indent_level -= 1; + self.emit_line(")"); + } + + AstNode::BreakStatement => { + self.emit_line(";; break"); + self.emit_line("br 1"); + } + + AstNode::ContinueStatement => { + self.emit_line(";; continue"); + self.emit_line("br 0"); + } + + AstNode::ExpressionStatement(expr) => { + self.emit_expression(expr); + self.emit_line("drop"); + } + + _ => { + self.emit_line(&format!(";; Unsupported statement: {:?}", stmt)); + } + } + } + + /// Emit an expression + fn emit_expression(&mut self, expr: &AstNode) { + match expr { + AstNode::NumberLiteral(n) => { + self.emit_line(&format!("f64.const {}", n)); + } + + AstNode::StringLiteral(s) => { + // For simplicity, emit string length (would need proper string handling) + self.emit_line(&format!( + "i32.const {} ;; string: {}", + s.len(), + s.escape_default() + )); + } + + AstNode::BooleanLiteral(b) => { + self.emit_line(&format!("i32.const {}", if *b { 1 } else { 0 })); + } + + AstNode::Identifier(name) => { + if let Some(&idx) = self.variable_map.get(name) { + self.emit_line(&format!("local.get ${}", idx)); + } else { + self.emit_line(&format!(";; undefined variable: {}", name)); + self.emit_line("f64.const 0"); + } + } + + AstNode::BinaryExpression { + left, + operator, + right, + } => { + self.emit_expression(left); + self.emit_expression(right); + + match operator.as_str() { + "+" => self.emit_line("f64.add"), + "-" => self.emit_line("f64.sub"), + "*" => self.emit_line("f64.mul"), + "/" => self.emit_line("f64.div"), + ">" | "LookAtTheWatch" => { + self.emit_line("f64.gt"); + } + "<" | "FallUnderMySpell" => { + self.emit_line("f64.lt"); + } + ">=" | "DeeplyGreater" => { + self.emit_line("f64.ge"); + } + "<=" | "DeeplyLess" => { + self.emit_line("f64.le"); + } + "==" | "YouAreFeelingVerySleepy" => { + self.emit_line("f64.eq"); + } + "!=" | "NotSoDeep" => { + self.emit_line("f64.ne"); + } + "&&" => { + self.emit_line("i32.and"); + } + "||" => { + self.emit_line("i32.or"); + } + _ => { + self.emit_line(&format!(";; unknown operator: {}", operator)); + } + } + } + + AstNode::UnaryExpression { operator, operand } => { + self.emit_expression(operand); + + match operator.as_str() { + "-" => self.emit_line("f64.neg"), + "!" => { + self.emit_line("i32.eqz"); + } + _ => { + self.emit_line(&format!(";; unknown unary operator: {}", operator)); + } + } + } + + AstNode::AssignmentExpression { target, value } => { + if let AstNode::Identifier(name) = target.as_ref() { + self.emit_expression(value); + if let Some(&idx) = self.variable_map.get(name) { + self.emit_line(&format!("local.tee ${}", idx)); + } + } + } + + _ => { + self.emit_line(&format!(";; Unsupported expression: {:?}", expr)); + self.emit_line("f64.const 0"); + } + } + } + + /// Emit a line with proper indentation + fn emit_line(&mut self, line: &str) { + let indent = " ".repeat(self.indent_level); + self.output.push_str(&format!("{}{}\n", indent, line)); + } + + /// Get next label + fn next_label(&mut self) -> String { + let label = format!("label{}", self.label_counter); + self.label_counter += 1; + label + } + + /// Get generated WASM code + pub fn get_output(&self) -> &str { + &self.output + } +} + +#[cfg(test)] +mod tests { + use super::*; + use hypnoscript_lexer_parser::{Lexer, Parser}; + + #[test] + fn test_wasm_generation_simple() { + let source = r#" +Focus { + induce x: number = 42; + induce y: number = 10; + observe x; +} Relax +"#; + let mut lexer = Lexer::new(source); + let tokens = lexer.lex().unwrap(); + let mut parser = Parser::new(tokens); + let ast = parser.parse_program().unwrap(); + + let mut generator = WasmCodeGenerator::new(); + let wasm = generator.generate(&ast); + + assert!(wasm.contains("(module")); + assert!(wasm.contains("func $main")); + assert!(wasm.contains("f64.const 42")); + } + + #[test] + fn test_wasm_generation_arithmetic() { + let source = r#" +Focus { + induce result: number = 10 + 20; + observe result; +} Relax +"#; + let mut lexer = Lexer::new(source); + let tokens = lexer.lex().unwrap(); + let mut parser = Parser::new(tokens); + let ast = parser.parse_program().unwrap(); + + let mut generator = WasmCodeGenerator::new(); + let wasm = generator.generate(&ast); + + assert!(wasm.contains("f64.add")); + } +} diff --git a/hypnoscript-core/Cargo.toml b/hypnoscript-core/Cargo.toml new file mode 100644 index 0000000..7295943 --- /dev/null +++ b/hypnoscript-core/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "hypnoscript-core" +version.workspace = true +edition.workspace = true +authors.workspace = true +license.workspace = true +repository.workspace = true + +[dependencies] +serde = { workspace = true } +serde_json = { workspace = true } diff --git a/hypnoscript-core/src/lib.rs b/hypnoscript-core/src/lib.rs new file mode 100644 index 0000000..56bfdf0 --- /dev/null +++ b/hypnoscript-core/src/lib.rs @@ -0,0 +1,13 @@ +//! HypnoScript Core Library +//! +//! This module provides the core types and data structures for the HypnoScript language, +//! including the type system, symbols, and symbol tables. + +pub mod symbol_table; +pub mod symbols; +pub mod types; + +// Re-export commonly used types +pub use symbol_table::SymbolTable; +pub use symbols::{Symbol, SymbolKind}; +pub use types::{HypnoBaseType, HypnoType}; diff --git a/hypnoscript-core/src/symbol_table.rs b/hypnoscript-core/src/symbol_table.rs new file mode 100644 index 0000000..a1bed02 --- /dev/null +++ b/hypnoscript-core/src/symbol_table.rs @@ -0,0 +1,250 @@ +use crate::symbols::{Symbol, SymbolKind}; +use std::collections::HashMap; + +/// Symbol table for managing scopes and variable bindings +#[derive(Debug, Clone)] +pub struct SymbolTable { + enclosing: Option>, + symbols: HashMap, + child_scopes: Vec, + pub scope_name: String, + pub scope_level: usize, +} + +impl SymbolTable { + /// Create a new symbol table + pub fn new(enclosing: Option>, scope_name: String) -> Self { + let scope_level = enclosing.as_ref().map(|e| e.scope_level + 1).unwrap_or(0); + Self { + enclosing, + symbols: HashMap::new(), + child_scopes: Vec::new(), + scope_name, + scope_level, + } + } + + /// Create a global scope + pub fn global() -> Self { + Self::new(None, "Global".to_string()) + } + + /// Define a new symbol in the current scope + pub fn define(&mut self, sym: Symbol) -> bool { + if self.symbols.contains_key(&sym.name) { + eprintln!( + "[SymbolTable] Symbol '{}' is already defined in scope '{}'.", + sym.name, self.scope_name + ); + return false; + } + self.symbols.insert(sym.name.clone(), sym); + true + } + + /// Resolve a symbol, looking in enclosing scopes if necessary + pub fn resolve(&self, name: &str) -> Option<&Symbol> { + self.symbols + .get(name) + .or_else(|| self.enclosing.as_ref().and_then(|e| e.resolve(name))) + } + + /// Resolve a symbol only in the current scope + pub fn resolve_local(&self, name: &str) -> Option<&Symbol> { + self.symbols.get(name) + } + + /// Check if a symbol exists (locally or in enclosing scopes) + pub fn has_symbol(&self, name: &str) -> bool { + self.resolve(name).is_some() + } + + /// Remove a symbol from the current scope + pub fn remove_symbol(&mut self, name: &str) -> bool { + self.symbols.remove(name).is_some() + } + + /// Clear all symbols from the current scope + pub fn clear(&mut self) { + self.symbols.clear(); + } + + /// Get all symbols in the current scope + pub fn get_all_symbols(&self) -> Vec<&Symbol> { + let mut symbols: Vec<_> = self.symbols.values().collect(); + symbols.sort_by(|a, b| a.name.cmp(&b.name)); + symbols + } + + /// Get symbols by kind + pub fn get_symbols_by_kind(&self, kind: SymbolKind) -> Vec<&Symbol> { + let mut symbols: Vec<_> = self.symbols.values().filter(|s| s.kind == kind).collect(); + symbols.sort_by(|a, b| a.name.cmp(&b.name)); + symbols + } + + /// Get exported symbols + pub fn get_exported_symbols(&self) -> Vec<&Symbol> { + let mut symbols: Vec<_> = self.symbols.values().filter(|s| s.is_exported).collect(); + symbols.sort_by(|a, b| a.name.cmp(&b.name)); + symbols + } + + /// Get constants + pub fn get_constants(&self) -> Vec<&Symbol> { + let mut symbols: Vec<_> = self.symbols.values().filter(|s| s.is_constant).collect(); + symbols.sort_by(|a, b| a.name.cmp(&b.name)); + symbols + } + + /// Get symbol count + pub fn symbol_count(&self) -> usize { + self.symbols.len() + } + + /// Get the enclosing scope + pub fn get_enclosing_scope(&self) -> Option<&SymbolTable> { + self.enclosing.as_ref().map(|e| e.as_ref()) + } + + /// Get child scopes + pub fn get_child_scopes(&self) -> &[SymbolTable] { + &self.child_scopes + } + + /// Get the root scope + pub fn get_root_scope(&self) -> &SymbolTable { + let mut current = self; + while let Some(ref enclosing) = current.enclosing { + current = enclosing; + } + current + } + + /// Get scope depth + pub fn get_scope_depth(&self) -> usize { + let mut depth = 0; + let mut current = self; + while let Some(ref enclosing) = current.enclosing { + depth += 1; + current = enclosing; + } + depth + } + + /// Get symbol statistics + pub fn get_symbol_statistics(&self) -> HashMap { + let mut stats = HashMap::new(); + for symbol in self.symbols.values() { + *stats.entry(symbol.kind).or_insert(0) += 1; + } + stats + } + + /// Get a scope summary + pub fn get_scope_summary(&self) -> String { + let stats = self.get_symbol_statistics(); + let mut summary = format!( + "Scope '{}' (Level {}): {} symbols\n", + self.scope_name, + self.scope_level, + self.symbol_count() + ); + + let mut kinds: Vec<_> = stats.keys().collect(); + kinds.sort(); + for kind in kinds { + if let Some(count) = stats.get(kind) { + summary.push_str(&format!(" {:?}: {}\n", kind, count)); + } + } + summary + } + + /// Search symbols by pattern + pub fn search_symbols(&self, pattern: &str, kind: Option) -> Vec<&Symbol> { + let pattern_lower = pattern.to_lowercase(); + let mut symbols: Vec<_> = self + .symbols + .values() + .filter(|s| { + let name_match = s.name.to_lowercase().contains(&pattern_lower); + let kind_match = kind.is_none_or(|k| s.kind == k); + name_match && kind_match + }) + .collect(); + symbols.sort_by(|a, b| a.name.cmp(&b.name)); + symbols + } + + /// Validate symbols + pub fn validate_symbols(&self) -> Vec { + let mut errors = Vec::new(); + + for symbol in self.symbols.values() { + if symbol.name.trim().is_empty() { + errors.push(format!( + "Symbol has empty name in scope '{}'", + self.scope_name + )); + } + + if symbol.kind == SymbolKind::Function && symbol.type_name.is_none() { + errors.push(format!("Function '{}' has no return type", symbol.name)); + } + } + + errors + } + + /// Merge symbols from another symbol table + pub fn merge_from(&mut self, other: &SymbolTable, overwrite: bool) { + for (name, symbol) in &other.symbols { + if overwrite || !self.symbols.contains_key(name) { + self.symbols.insert(name.clone(), symbol.clone()); + } + } + } + + /// Export only exported symbols to a new scope + pub fn export_scope(&self) -> SymbolTable { + let mut exported = SymbolTable::new(None, format!("{}_Exported", self.scope_name)); + for symbol in self.symbols.values() { + if symbol.is_exported { + exported.define(symbol.clone()); + } + } + exported + } + + /// Debug scope information + pub fn debug_scope(&self) -> String { + let mut result = format!( + "Scope '{}' (Level {}):\n", + self.scope_name, self.scope_level + ); + + let mut symbols: Vec<_> = self.symbols.iter().collect(); + symbols.sort_by(|a, b| a.0.cmp(b.0)); + + for (name, symbol) in symbols { + let const_info = if symbol.is_constant { " (const)" } else { "" }; + let export_info = if symbol.is_exported { + " (exported)" + } else { + "" + }; + result.push_str(&format!( + " {:?} {}: {:?}{}{}\n", + symbol.kind, name, symbol.type_name, const_info, export_info + )); + } + + if let Some(ref enclosing) = self.enclosing { + result.push_str("\nEnclosing Scope:\n"); + result.push_str(&enclosing.debug_scope()); + } + + result + } +} diff --git a/hypnoscript-core/src/symbols.rs b/hypnoscript-core/src/symbols.rs new file mode 100644 index 0000000..a97cd13 --- /dev/null +++ b/hypnoscript-core/src/symbols.rs @@ -0,0 +1,158 @@ +use crate::types::HypnoType; +use serde::{Deserialize, Serialize}; + +/// Kind of symbol in the symbol table +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)] +pub enum SymbolKind { + Variable, + Function, + Session, + Record, + Parameter, + Label, + Builtin, + Module, +} + +/// Represents a symbol in the HypnoScript symbol table +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Symbol { + pub name: String, + pub type_name: Option, + pub kind: SymbolKind, + pub hypno_type: Option, + pub is_constant: bool, + pub is_exported: bool, + pub documentation: Option, + pub line_number: usize, + pub column_number: usize, +} + +impl Symbol { + /// Create a new symbol + pub fn new(name: String, type_name: Option, kind: SymbolKind) -> Self { + Self { + name, + type_name, + kind, + hypno_type: None, + is_constant: false, + is_exported: false, + documentation: None, + line_number: 0, + column_number: 0, + } + } + + /// Create a new symbol with type + pub fn with_type(name: String, hypno_type: HypnoType, kind: SymbolKind) -> Self { + Self { + name, + type_name: None, + kind, + hypno_type: Some(hypno_type), + is_constant: false, + is_exported: false, + documentation: None, + line_number: 0, + column_number: 0, + } + } + + /// Factory method for creating a variable + pub fn create_variable(name: String, type_name: String) -> Self { + Self::new(name, Some(type_name), SymbolKind::Variable) + } + + /// Factory method for creating a function + pub fn create_function( + name: String, + return_type: String, + documentation: Option, + ) -> Self { + let mut sym = Self::new(name, Some(return_type), SymbolKind::Function); + sym.documentation = documentation; + sym + } + + /// Factory method for creating a session + pub fn create_session(name: String, documentation: Option) -> Self { + let mut sym = Self::new(name, Some("session".to_string()), SymbolKind::Session); + sym.documentation = documentation; + sym + } + + /// Factory method for creating a record + pub fn create_record(name: String, documentation: Option) -> Self { + let mut sym = Self::new(name, Some("record".to_string()), SymbolKind::Record); + sym.documentation = documentation; + sym + } + + /// Factory method for creating a builtin + pub fn create_builtin( + name: String, + return_type: String, + documentation: Option, + ) -> Self { + let mut sym = Self::new(name, Some(return_type), SymbolKind::Builtin); + sym.documentation = documentation; + sym + } + + /// Factory method for creating a label + pub fn create_label(name: String) -> Self { + Self::new(name, None, SymbolKind::Label) + } + + /// Check if symbol is a function + pub fn is_function(&self) -> bool { + matches!(self.kind, SymbolKind::Function | SymbolKind::Builtin) + } + + /// Check if symbol is a type + pub fn is_type(&self) -> bool { + matches!(self.kind, SymbolKind::Session | SymbolKind::Record) + } + + /// Check if symbol is a variable + pub fn is_variable(&self) -> bool { + matches!(self.kind, SymbolKind::Variable | SymbolKind::Parameter) + } + + /// Get full description of the symbol + pub fn get_full_description(&self) -> String { + let mut result = format!("{:?} '{}'", self.kind, self.name); + + if let Some(ref t) = self.hypno_type { + result.push_str(&format!(" of type {}", t)); + } else if let Some(ref tn) = self.type_name { + result.push_str(&format!(" of type {}", tn)); + } + + if self.is_constant { + result.push_str(" (constant)"); + } + if self.is_exported { + result.push_str(" (exported)"); + } + if let Some(ref doc) = self.documentation { + result.push_str(&format!(" - {}", doc)); + } + + result + } +} + +impl std::fmt::Display for Symbol { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let type_info = self + .hypno_type + .as_ref() + .map(|t| t.to_string()) + .or_else(|| self.type_name.clone()) + .unwrap_or_else(|| "unknown".to_string()); + let kind_info = format!("{:?}", self.kind).to_lowercase(); + write!(f, "{} {}: {}", kind_info, self.name, type_info) + } +} diff --git a/hypnoscript-core/src/types.rs b/hypnoscript-core/src/types.rs new file mode 100644 index 0000000..103e879 --- /dev/null +++ b/hypnoscript-core/src/types.rs @@ -0,0 +1,230 @@ +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; +use std::fmt; + +/// Base types in HypnoScript language +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub enum HypnoBaseType { + Number, + String, + Boolean, + Trance, + Array, + Object, + Function, + Session, + Record, + Unknown, +} + +/// Represents a type in the HypnoScript type system +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct HypnoType { + pub base_type: HypnoBaseType, + pub name: Option, + pub element_type: Option>, + pub fields: Option>, + pub parameter_types: Option>, + pub return_type: Option>, +} + +impl HypnoType { + /// Create a new simple type + pub fn new(base_type: HypnoBaseType, name: Option) -> Self { + Self { + base_type, + name, + element_type: None, + fields: None, + parameter_types: None, + return_type: None, + } + } + + /// Create an array type + pub fn create_array(element_type: HypnoType) -> Self { + Self { + base_type: HypnoBaseType::Array, + name: None, + element_type: Some(Box::new(element_type)), + fields: None, + parameter_types: None, + return_type: None, + } + } + + /// Create a record type + pub fn create_record(name: String, fields: HashMap) -> Self { + Self { + base_type: HypnoBaseType::Record, + name: Some(name), + element_type: None, + fields: Some(fields), + parameter_types: None, + return_type: None, + } + } + + /// Create a function type + pub fn create_function(parameter_types: Vec, return_type: HypnoType) -> Self { + Self { + base_type: HypnoBaseType::Function, + name: None, + element_type: None, + fields: None, + parameter_types: Some(parameter_types), + return_type: Some(Box::new(return_type)), + } + } + + /// Predefined type constants + pub fn number() -> Self { + Self::new(HypnoBaseType::Number, None) + } + + pub fn string() -> Self { + Self::new(HypnoBaseType::String, None) + } + + pub fn boolean() -> Self { + Self::new(HypnoBaseType::Boolean, None) + } + + pub fn unknown() -> Self { + Self::new(HypnoBaseType::Unknown, None) + } + + /// Type checking predicates + pub fn is_array(&self) -> bool { + self.base_type == HypnoBaseType::Array + } + + pub fn is_record(&self) -> bool { + self.base_type == HypnoBaseType::Record + } + + pub fn is_function(&self) -> bool { + self.base_type == HypnoBaseType::Function + } + + pub fn is_primitive(&self) -> bool { + matches!( + self.base_type, + HypnoBaseType::Number | HypnoBaseType::String | HypnoBaseType::Boolean + ) + } + + /// Check if this type is compatible with another type + pub fn is_compatible_with(&self, other: &HypnoType) -> bool { + if self.base_type != other.base_type { + return false; + } + + match self.base_type { + HypnoBaseType::Array => { + if let (Some(ref elem1), Some(ref elem2)) = + (&self.element_type, &other.element_type) + { + elem1.is_compatible_with(elem2) + } else { + false + } + } + HypnoBaseType::Record => { + if let (Some(ref fields1), Some(ref fields2)) = (&self.fields, &other.fields) { + if fields1.len() != fields2.len() { + return false; + } + fields1.iter().all(|(key, value)| { + fields2 + .get(key) + .is_some_and(|v| value.is_compatible_with(v)) + }) + } else { + false + } + } + HypnoBaseType::Function => { + if let (Some(ref params1), Some(ref params2)) = + (&self.parameter_types, &other.parameter_types) + { + if params1.len() != params2.len() { + return false; + } + let params_match = params1 + .iter() + .zip(params2.iter()) + .all(|(p1, p2)| p1.is_compatible_with(p2)); + + let return_match = match (&self.return_type, &other.return_type) { + (Some(ref ret1), Some(ref ret2)) => ret1.is_compatible_with(ret2), + (None, None) => true, + _ => false, + }; + + params_match && return_match + } else { + false + } + } + _ => true, + } + } +} + +impl fmt::Display for HypnoType { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self.base_type { + HypnoBaseType::Array => { + if let Some(ref elem) = self.element_type { + write!(f, "[{}]", elem) + } else { + write!(f, "Array") + } + } + HypnoBaseType::Record => { + if let Some(ref name) = self.name { + write!(f, "Record<{}>", name) + } else { + write!(f, "Record") + } + } + HypnoBaseType::Function => { + let params = self + .parameter_types + .as_ref() + .map(|p| { + p.iter() + .map(|t| t.to_string()) + .collect::>() + .join(",") + }) + .unwrap_or_default(); + let ret = self + .return_type + .as_ref() + .map(|r| r.to_string()) + .unwrap_or_else(|| "void".to_string()); + write!(f, "Function<{} -> {}>", params, ret) + } + _ => { + if let Some(ref name) = self.name { + write!(f, "{}", name) + } else { + write!(f, "{:?}", self.base_type) + } + } + } + } +} + +impl std::hash::Hash for HypnoType { + fn hash(&self, state: &mut H) { + self.base_type.hash(state); + self.name.hash(state); + // Note: We don't hash all fields for simplicity + // This is a reasonable compromise for the type system + } +} + +impl Eq for HypnoType {} diff --git a/HypnoScript.Dokumentation/.gitignore b/hypnoscript-docs/.gitignore similarity index 96% rename from HypnoScript.Dokumentation/.gitignore rename to hypnoscript-docs/.gitignore index b2d6de3..35c69a7 100644 --- a/HypnoScript.Dokumentation/.gitignore +++ b/hypnoscript-docs/.gitignore @@ -18,3 +18,5 @@ npm-debug.log* yarn-debug.log* yarn-error.log* + +*dist/ diff --git a/HypnoScript.Dokumentation/README.md b/hypnoscript-docs/README.md similarity index 77% rename from HypnoScript.Dokumentation/README.md rename to hypnoscript-docs/README.md index f2e9a14..684ab85 100644 --- a/HypnoScript.Dokumentation/README.md +++ b/hypnoscript-docs/README.md @@ -1,13 +1,13 @@ # HypnoScript Dokumentation -Dies ist die vollständige Dokumentation für HypnoScript - Die hypnotische Programmiersprache. Die Dokumentation wird mit [Docusaurus 3.8](https://docusaurus.io/) erstellt und automatisch zu GitHub Pages deployed. +Dies ist die vollständige Dokumentation für HypnoScript - Die hypnotische Programmiersprache. Die Dokumentation wird mit [VitePress](https://vitepress.dev/) erstellt und automatisch zu GitHub Pages deployed. ## 🚀 Schnellstart ### Voraussetzungen - Node.js 18.0 oder höher -- npm oder yarn +- npm, yarn oder pnpm ### Installation @@ -16,13 +16,13 @@ Dies ist die vollständige Dokumentation für HypnoScript - Die hypnotische Prog npm install # Entwicklungsserver starten -npm start +npm run dev # Dokumentation bauen npm run build -# Lokalen Server für gebaute Dokumentation starten -npm run serve +# Vorschau der gebauten Dokumentation +npm run preview ``` ## 📁 Projektstruktur @@ -30,6 +30,12 @@ npm run serve ``` HypnoScript.Dokumentation/ ├── docs/ # Dokumentationsseiten +│ ├── .vitepress/ # VitePress-Konfiguration +│ │ ├── config.mts # Hauptkonfiguration +│ │ └── theme/ # Custom Theme +│ │ ├── index.ts # Theme-Einstiegspunkt +│ │ └── style.css # Custom CSS +│ ├── index.md # Homepage │ ├── intro.md # Einführung │ ├── getting-started/ # Erste Schritte │ ├── language-reference/ # Sprachreferenz @@ -38,15 +44,9 @@ HypnoScript.Dokumentation/ │ ├── examples/ # Beispiele │ ├── development/ # Entwicklung │ └── reference/ # Referenz -├── blog/ # Blog-Posts -├── src/ # Quellcode -│ ├── css/ # Custom CSS -│ └── pages/ # Zusätzliche Seiten -├── static/ # Statische Dateien -│ └── img/ # Bilder -├── docusaurus.config.js # Docusaurus-Konfiguration -├── sidebars.js # Sidebar-Struktur -└── package.json # Dependencies +├── static/ # Statische Dateien +│ └── img/ # Bilder +└── package.json # Dependencies ``` ## 🛠️ Entwicklung @@ -54,26 +54,27 @@ HypnoScript.Dokumentation/ ### Neue Seite hinzufügen 1. Erstelle eine neue `.md` Datei im entsprechenden Verzeichnis unter `docs/` -2. Füge Frontmatter hinzu: +2. Füge Frontmatter hinzu (optional): ```markdown --- - sidebar_position: 1 + title: Seitentitel + description: Beschreibung --- ``` -3. Aktualisiere `sidebars.js` um die Seite in die Navigation einzufügen +3. Aktualisiere `docs/.vitepress/config.mts` um die Seite in die Sidebar einzufügen ### Styling anpassen -- Custom CSS: `src/css/custom.css` -- Theme-Komponenten: `src/theme/` +- Custom CSS: `docs/.vitepress/theme/style.css` +- Theme-Komponenten: `docs/.vitepress/theme/index.ts` ### Lokale Entwicklung ```bash -npm start +npm run dev ``` -Öffne [http://localhost:3000](http://localhost:3000) im Browser. +Öffne [http://localhost:5173](http://localhost:5173) im Browser. ## 🚀 Deployment @@ -87,7 +88,7 @@ Die Dokumentation wird automatisch zu GitHub Pages deployed über GitHub Actions ```bash npm run build -npm run deploy +# Die gebaute Dokumentation befindet sich in docs/.vitepress/dist/ ``` ## 📚 Dokumentationsstruktur diff --git a/hypnoscript-docs/docs/.vitepress/config.mts b/hypnoscript-docs/docs/.vitepress/config.mts new file mode 100644 index 0000000..f58933e --- /dev/null +++ b/hypnoscript-docs/docs/.vitepress/config.mts @@ -0,0 +1,239 @@ +import type { LanguageRegistration } from 'shiki'; +import { createHighlighter } from 'shiki'; +import { defineConfig } from 'vitepress'; +import hypnoscriptGrammar from './hypnoscript.tmLanguage.json' with { type: 'json' }; + +const BASE_PATH = '/hyp-runtime/'; + +const hypnoscriptLanguage = { + ...hypnoscriptGrammar, + name: 'HypnoScript', + aliases: ['hypnoscript', 'hyp', 'hypno'], + embeddedLangs: ['json', 'javascript'], +} satisfies LanguageRegistration; + +const LANGUAGE_ALIASES: Record = { + bash: 'bash', + console: 'bash', + sh: 'bash', + shell: 'bash', + shellscript: 'bash', + js: 'javascript', + javascript: 'javascript', + ts: 'typescript', + typescript: 'typescript', + json: 'json', + jsonc: 'json', + yml: 'yaml', + yaml: 'yaml', + md: 'markdown', + markdown: 'markdown', + hyp: 'hypnoscript', + hypno: 'hypnoscript', + hypnoscript: 'hypnoscript', +}; + +const highlighter = await createHighlighter({ + themes: ['github-light', 'github-dark'], + langs: [ + 'bash', + 'css', + 'html', + 'javascript', + 'json', + 'markdown', + 'powershell', + 'rust', + 'toml', + 'typescript', + 'yaml', + 'text', + hypnoscriptLanguage, + ], +}); + +const loadedLanguages = new Set( + highlighter + .getLoadedLanguages() + .map((lang) => (typeof lang === 'string' ? lang.toLowerCase() : '')) + .filter(Boolean) as string[], +); + +const resolveLanguage = (rawLang: string | undefined): string => { + const normalized = (rawLang ?? '').trim().toLowerCase(); + if (!normalized) { + return 'text'; + } + + const aliased = LANGUAGE_ALIASES[normalized]; + if (aliased && loadedLanguages.has(aliased)) { + return aliased; + } + + if (loadedLanguages.has(normalized)) { + return normalized; + } + + for (const candidate of loadedLanguages) { + const language = highlighter.getLanguage(candidate) as unknown as + | { aliases?: string[] } + | undefined; + if (language?.aliases?.some((alias) => alias.toLowerCase() === normalized)) { + return candidate; + } + } + + return 'text'; +}; + +const escapeVueInterpolation = (html: string): string => + html.replaceAll('{{', '{{').replaceAll('}}', '}}'); + +// https://vitepress.dev/reference/site-config +export default defineConfig({ + title: 'HypnoScript', + description: 'Code with style - Die hypnotische Programmiersprache', + base: BASE_PATH, + + // Ignoriere tote Links während der Migration + ignoreDeadLinks: true, + + head: [['link', { rel: 'icon', href: `${BASE_PATH}img/favicon.ico` }]], + + vite: { + publicDir: '../static', + }, + + themeConfig: { + // https://vitepress.dev/reference/default-theme-config + logo: '/img/logo.svg', + editLink: false as unknown as undefined, + + nav: [ + { text: 'Home', link: '/' }, + { text: 'Dokumentation', link: '/intro' }, + { + text: 'Erste Schritte', + items: [ + { text: 'Installation', link: '/getting-started/installation' }, + { text: 'Quick Start', link: '/getting-started/quick-start' }, + { text: 'CLI Basics', link: '/getting-started/cli-basics' }, + ], + }, + { + text: 'Referenz', + items: [ + { text: 'Sprachreferenz', link: '/language-reference/syntax' }, + { text: 'Builtin-Funktionen', link: '/builtins/overview' }, + { text: 'CLI Kommandos', link: '/cli/commands' }, + { text: 'Runtime', link: '/reference/runtime' }, + ], + }, + ], + + sidebar: { + '/': [ + { + text: 'Einführung', + items: [ + { text: 'Willkommen', link: '/intro' }, + { + text: 'Was ist HypnoScript?', + link: '/getting-started/what-is-hypnoscript', + }, + ], + }, + { + text: 'Erste Schritte', + collapsed: false, + items: [ + { text: 'Installation', link: '/getting-started/installation' }, + { text: 'Quick Start', link: '/getting-started/quick-start' }, + { text: 'Hello World', link: '/getting-started/hello-world' }, + { text: 'Grundkonzepte', link: '/getting-started/core-concepts' }, + { text: 'CLI Basics', link: '/getting-started/cli-basics' }, + ], + }, + { + text: 'Sprachreferenz', + collapsed: false, + items: [ + { text: 'Syntax & Struktur', link: '/language-reference/syntax' }, + { text: 'Variablen & Typen', link: '/language-reference/variables' }, + { text: 'Operatoren', link: '/language-reference/operators' }, + { text: 'Kontrollfluss', link: '/language-reference/control-flow' }, + { text: 'Funktionen & Trigger', link: '/language-reference/functions' }, + { text: 'Sessions', link: '/language-reference/sessions' }, + { text: 'Schlüsselwörter', link: '/language-reference/_keywords-reference' }, + ], + }, + { + text: 'Standardbibliothek', + collapsed: false, + items: [ + { text: 'Builtin-Übersicht', link: '/builtins/overview' }, + ], + }, + { + text: 'CLI', + collapsed: false, + items: [ + { text: 'Überblick', link: '/cli/overview' }, + { text: 'Befehle', link: '/cli/commands' }, + ], + }, + { + text: 'Referenz', + collapsed: false, + items: [ + { text: 'Runtime-Architektur', link: '/reference/runtime' }, + ], + }, + ], + }, + + socialLinks: [ + { + icon: 'github', + link: 'https://github.com/Kink-Development-Group/hyp-runtime', + }, + ], + + footer: { + message: 'Released under the MIT License.', + copyright: 'Copyright © 2024-present HypnoScript Team', + }, + + search: { + provider: 'local', + }, + + lastUpdated: { + text: 'Zuletzt aktualisiert', + formatOptions: { + dateStyle: 'medium', + timeStyle: 'short', + }, + }, + }, + + markdown: { + theme: { + light: 'github-light', + dark: 'github-dark', + }, + lineNumbers: true, + highlight(code, lang) { + const resolved = resolveLanguage(lang); + const highlighted = highlighter.codeToHtml(code, { + lang: resolved, + themes: { + light: 'github-light', + dark: 'github-dark', + }, + }); + + return escapeVueInterpolation(highlighted); + }, + }, +}); diff --git a/hypnoscript-docs/docs/.vitepress/hypnoscript.tmLanguage.json b/hypnoscript-docs/docs/.vitepress/hypnoscript.tmLanguage.json new file mode 100644 index 0000000..605d679 --- /dev/null +++ b/hypnoscript-docs/docs/.vitepress/hypnoscript.tmLanguage.json @@ -0,0 +1,107 @@ +{ + "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", + "name": "HypnoScript", + "scopeName": "source.hypnoscript", + "fileTypes": ["hyp", "hypnoscript"], + "patterns": [ + { "include": "#comments" }, + { "include": "#strings" }, + { "include": "#numbers" }, + { "include": "#keywords" }, + { "include": "#types" }, + { "include": "#operators" }, + { "include": "#builtins" } + ], + "repository": { + "comments": { + "patterns": [ + { + "name": "comment.line.double-slash.hypnoscript", + "match": "//.*$" + }, + { + "name": "comment.block.hypnoscript", + "begin": "/\\*", + "end": "\\*/" + } + ] + }, + "strings": { + "patterns": [ + { + "name": "string.quoted.double.hypnoscript", + "begin": "\"", + "end": "\"", + "beginCaptures": { + "0": { + "name": "punctuation.definition.string.begin.hypnoscript" + } + }, + "endCaptures": { + "0": { + "name": "punctuation.definition.string.end.hypnoscript" + } + }, + "patterns": [ + { + "name": "constant.character.escape.hypnoscript", + "match": "\\\\." + } + ] + } + ] + }, + "numbers": { + "patterns": [ + { + "name": "constant.numeric.decimal.hypnoscript", + "match": "\\b[0-9]+(\\.[0-9_]+)?\\b" + } + ] + }, + "keywords": { + "patterns": [ + { + "name": "keyword.control.hypnoscript", + "match": "\\b(?:focus|relax|entrance|exit|if|else|elseif|while|for|loop|break|continue|return|try|catch|finally|on|warn)\\b" + }, + { + "name": "keyword.other.directive.hypnoscript", + "match": "\\b(?:induce|observe|suggest|assert|log|listen|invoke|transition|awaken|deepFocus|lightFocus|anchor|release|guard)\\b" + } + ] + }, + "types": { + "patterns": [ + { + "name": "storage.type.hypnoscript", + "match": "\\b(?:string|number|boolean|array|dictionary|session|duration|moment|signal|void)\\b" + } + ] + }, + "operators": { + "patterns": [ + { + "name": "keyword.operator.hypnoscript", + "match": "==|!=|<=|>=|<|>|\\+|-|\\*|/|%|&&|\\|\\||!" + }, + { + "name": "keyword.operator.word.hypnoscript", + "match": "\\b(?:and|or|not|youAreFeelingVerySleepy|youAreAwakeNow)\\b" + } + ] + }, + "builtins": { + "patterns": [ + { + "name": "support.function.hypnoscript", + "match": "\\b[A-Z][A-Za-z0-9_]*(?=\\()" + }, + { + "name": "support.namespace.hypnoscript", + "match": "\\b[A-Z][A-Za-z0-9_]*(?=::)" + } + ] + } + } +} diff --git a/hypnoscript-docs/docs/.vitepress/theme/index.ts b/hypnoscript-docs/docs/.vitepress/theme/index.ts new file mode 100644 index 0000000..fccaf72 --- /dev/null +++ b/hypnoscript-docs/docs/.vitepress/theme/index.ts @@ -0,0 +1,17 @@ +// https://vitepress.dev/guide/custom-theme +import { h } from 'vue'; +import type { Theme } from 'vitepress'; +import DefaultTheme from 'vitepress/theme'; +import './style.css'; + +export default { + extends: DefaultTheme, + Layout: () => { + return h(DefaultTheme.Layout, null, { + // https://vitepress.dev/guide/extending-default-theme#layout-slots + }); + }, + enhanceApp({ app, router, siteData }) { + // ... + }, +} satisfies Theme; diff --git a/hypnoscript-docs/docs/.vitepress/theme/style.css b/hypnoscript-docs/docs/.vitepress/theme/style.css new file mode 100644 index 0000000..0359f54 --- /dev/null +++ b/hypnoscript-docs/docs/.vitepress/theme/style.css @@ -0,0 +1,138 @@ +/** + * Customize default theme styling by overriding CSS variables: + * https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css + */ + +/** + * Colors + * + * Each colors have exact same color scale system with 3 levels of solid + * colors with different brightness, and 1 soft color. + * + * - `XXX-1`: The most solid color used mainly for colored text. It must + * satisfy the contrast ratio against when used on top of `XXX-soft`. + * + * - `XXX-2`: The color used mainly for hover state of the button. + * + * - `XXX-3`: The color for solid background, such as bg color of the button. + * It must satisfy the contrast ratio with pure white (#ffffff) text on + * top of it. + * + * - `XXX-soft`: The color used for subtle background such as custom container + * or badges. It must satisfy the contrast ratio when putting `XXX-1` colors + * on top of it. + * + * The soft color must be semi transparent alpha channel. This is crucial + * because it allows adding multiple "soft" colors on top of each other + * to create a accent, such as when having inline code block inside + * custom containers. + * + * - `default`: The color used purely for subtle indication without any + * special meanings attached to it such as bg color for menu hover state. + * + * - `brand`: Used for primary brand colors, such as link text, button with + * brand theme, etc. + * + * - `tip`: Used to indicate useful information. The default theme uses the + * brand color for this by default. + * + * - `warning`: Used to indicate warning to the users. Used in custom + * container, badges, etc. + * + * - `danger`: Used to show error, or dangerous message to the users. Used + * in custom container, badges, etc. + * -------------------------------------------------------------------------- */ + +:root { + --vp-c-default-1: var(--vp-c-gray-1); + --vp-c-default-2: var(--vp-c-gray-2); + --vp-c-default-3: var(--vp-c-gray-3); + --vp-c-default-soft: var(--vp-c-gray-soft); + + --vp-c-brand-1: #9333ea; + --vp-c-brand-2: #a855f7; + --vp-c-brand-3: #c084fc; + --vp-c-brand-soft: rgba(147, 51, 234, 0.14); + + --vp-c-tip-1: var(--vp-c-brand-1); + --vp-c-tip-2: var(--vp-c-brand-2); + --vp-c-tip-3: var(--vp-c-brand-3); + --vp-c-tip-soft: var(--vp-c-brand-soft); + + --vp-c-warning-1: #e7a700; + --vp-c-warning-2: #f0bb00; + --vp-c-warning-3: #ffc700; + --vp-c-warning-soft: rgba(255, 199, 0, 0.14); + + --vp-c-danger-1: #e0245e; + --vp-c-danger-2: #f72d6a; + --vp-c-danger-3: #ff3a75; + --vp-c-danger-soft: rgba(255, 58, 117, 0.14); +} + +/** + * Component: Button + * -------------------------------------------------------------------------- */ + +:root { + --vp-button-brand-border: transparent; + --vp-button-brand-text: var(--vp-c-white); + --vp-button-brand-bg: var(--vp-c-brand-3); + --vp-button-brand-hover-border: transparent; + --vp-button-brand-hover-text: var(--vp-c-white); + --vp-button-brand-hover-bg: var(--vp-c-brand-2); + --vp-button-brand-active-border: transparent; + --vp-button-brand-active-text: var(--vp-c-white); + --vp-button-brand-active-bg: var(--vp-c-brand-1); +} + +/** + * Component: Home + * -------------------------------------------------------------------------- */ + +:root { + --vp-home-hero-name-color: transparent; + --vp-home-hero-name-background: -webkit-linear-gradient( + 120deg, + #9333ea 30%, + #c084fc + ); + + --vp-home-hero-image-background-image: linear-gradient( + -45deg, + #9333ea 50%, + #c084fc 50% + ); + --vp-home-hero-image-filter: blur(44px); +} + +@media (min-width: 640px) { + :root { + --vp-home-hero-image-filter: blur(56px); + } +} + +@media (min-width: 960px) { + :root { + --vp-home-hero-image-filter: blur(68px); + } +} + +/** + * Component: Custom Block + * -------------------------------------------------------------------------- */ + +:root { + --vp-custom-block-tip-border: transparent; + --vp-custom-block-tip-text: var(--vp-c-text-1); + --vp-custom-block-tip-bg: var(--vp-c-brand-soft); + --vp-custom-block-tip-code-bg: var(--vp-c-brand-soft); +} + +/** + * Component: Algolia + * -------------------------------------------------------------------------- */ + +.DocSearch { + --docsearch-primary-color: var(--vp-c-brand-1) !important; +} diff --git a/hypnoscript-docs/docs/.vitepress/theme/style.css.d.ts b/hypnoscript-docs/docs/.vitepress/theme/style.css.d.ts new file mode 100644 index 0000000..35306c6 --- /dev/null +++ b/hypnoscript-docs/docs/.vitepress/theme/style.css.d.ts @@ -0,0 +1 @@ +declare module '*.css'; diff --git a/hypnoscript-docs/docs/builtins/_complete-reference.md b/hypnoscript-docs/docs/builtins/_complete-reference.md new file mode 100644 index 0000000..c981546 --- /dev/null +++ b/hypnoscript-docs/docs/builtins/_complete-reference.md @@ -0,0 +1,407 @@ +# Builtin-Funktionen Vollständige Referenz + +Vollständige Referenz aller 110+ Builtin-Funktionen in HypnoScript (Rust-Edition). + +## Core Builtins (I/O & Konvertierung) + +### Ausgabe-Funktionen + +| Funktion | Signatur | Beschreibung | +| --------- | ------------------------- | ---------------------------------- | +| `observe` | `(value: string) -> void` | Standard-Ausgabe mit Zeilenumbruch | +| `whisper` | `(value: string) -> void` | Ausgabe ohne Zeilenumbruch | +| `command` | `(value: string) -> void` | Ausgabe in Großbuchstaben | +| `drift` | `(ms: number) -> void` | Pause/Sleep (in Millisekunden) | + +### Hypnotische Funktionen + +| Funktion | Signatur | Beschreibung | +| ----------------------- | ------------------------------- | -------------------------------------- | +| `DeepTrance` | `(duration: number) -> void` | Tiefe Trance-Induktion mit Verzögerung | +| `HypnoticCountdown` | `(from: number) -> void` | Hypnotischer Countdown | +| `TranceInduction` | `(subjectName: string) -> void` | Vollständige Trance-Induktion | +| `HypnoticVisualization` | `(scene: string) -> void` | Hypnotische Visualisierung | + +### Konvertierungs-Funktionen + +| Funktion | Signatur | Beschreibung | +| ----------- | ---------------------------- | --------------------------------- | +| `ToInt` | `(value: number) -> number` | Konvertiert zu Integer (truncate) | +| `ToDouble` | `(value: string) -> number` | Parse String zu number | +| `ToString` | `(value: any) -> string` | Konvertiert zu String | +| `ToBoolean` | `(value: string) -> boolean` | Parse String zu boolean | + +## Math Builtins + +### Trigonometrische Funktionen + +| Funktion | Signatur | Beschreibung | +| -------- | ----------------------- | ------------ | +| `Sin` | `(x: number) -> number` | Sinus | +| `Cos` | `(x: number) -> number` | Cosinus | +| `Tan` | `(x: number) -> number` | Tangens | + +### Wurzel & Potenz + +| Funktion | Signatur | Beschreibung | +| -------- | -------------------------------------------- | ------------- | +| `Sqrt` | `(x: number) -> number` | Quadratwurzel | +| `Pow` | `(base: number, exponent: number) -> number` | Potenz | + +### Logarithmen + +| Funktion | Signatur | Beschreibung | +| -------- | ----------------------- | ---------------------------- | +| `Log` | `(x: number) -> number` | Natürlicher Logarithmus (ln) | +| `Log10` | `(x: number) -> number` | Logarithmus zur Basis 10 | + +### Rundung + +| Funktion | Signatur | Beschreibung | +| -------- | ----------------------- | --------------------- | +| `Abs` | `(x: number) -> number` | Absoluter Wert | +| `Floor` | `(x: number) -> number` | Abrunden | +| `Ceil` | `(x: number) -> number` | Aufrunden | +| `Round` | `(x: number) -> number` | Kaufmännisches Runden | + +### Min/Max + +| Funktion | Signatur | Beschreibung | +| -------- | ----------------------------------------------------- | -------------- | +| `Min` | `(a: number, b: number) -> number` | Minimum | +| `Max` | `(a: number, b: number) -> number` | Maximum | +| `Clamp` | `(value: number, min: number, max: number) -> number` | Wert begrenzen | + +### Zahlentheorie + +| Funktion | Signatur | Beschreibung | +| ----------- | ---------------------------------- | -------------------------------- | +| `Factorial` | `(n: number) -> number` | Fakultät | +| `Gcd` | `(a: number, b: number) -> number` | Größter gemeinsamer Teiler | +| `Lcm` | `(a: number, b: number) -> number` | Kleinstes gemeinsames Vielfaches | +| `IsPrime` | `(n: number) -> boolean` | Prüft ob Primzahl | +| `Fibonacci` | `(n: number) -> number` | n-te Fibonacci-Zahl | + +## String Builtins + +### Basis-Operationen + +| Funktion | Signatur | Beschreibung | +| ------------ | ----------------------- | ---------------------- | +| `Length` | `(s: string) -> number` | String-Länge | +| `ToUpper` | `(s: string) -> string` | In Großbuchstaben | +| `ToLower` | `(s: string) -> string` | In Kleinbuchstaben | +| `Trim` | `(s: string) -> string` | Whitespace entfernen | +| `Reverse` | `(s: string) -> string` | String umkehren | +| `Capitalize` | `(s: string) -> string` | Ersten Buchstaben groß | + +### Suchen & Ersetzen + +| Funktion | Signatur | Beschreibung | +| ------------ | ------------------------------------------------- | --------------------------------------------- | +| `IndexOf` | `(s: string, pattern: string) -> number` | Index des Substrings (-1 wenn nicht gefunden) | +| `Replace` | `(s: string, from: string, to: string) -> string` | Alle Vorkommen ersetzen | +| `Contains` | `(s: string, pattern: string) -> boolean` | Prüft ob enthalten | +| `StartsWith` | `(s: string, prefix: string) -> boolean` | Prüft Präfix | +| `EndsWith` | `(s: string, suffix: string) -> boolean` | Prüft Suffix | + +### Manipulation + +| Funktion | Signatur | Beschreibung | +| ----------- | ---------------------------------------------------- | ---------------------- | +| `Split` | `(s: string, delimiter: string) -> string[]` | String aufteilen | +| `Substring` | `(s: string, start: number, end: number) -> string` | Teilstring extrahieren | +| `Repeat` | `(s: string, times: number) -> string` | String wiederholen | +| `PadLeft` | `(s: string, width: number, char: string) -> string` | Links auffüllen | +| `PadRight` | `(s: string, width: number, char: string) -> string` | Rechts auffüllen | + +### Prüfungen + +| Funktion | Signatur | Beschreibung | +| -------------- | ------------------------ | ----------------------- | +| `IsEmpty` | `(s: string) -> boolean` | Prüft ob leer | +| `IsWhitespace` | `(s: string) -> boolean` | Prüft ob nur Whitespace | + +## Array Builtins + +:::note Array-Präfix +Alle Array-Funktionen verwenden das Präfix `Array` zur Unterscheidung von String-Funktionen (z.B. `ArrayLength` vs. String `Length`). +::: + +### Basis-Operationen + +| Funktion | Signatur | Beschreibung | +| --------------- | ----------------------------------- | ------------------------------------------- | +| `ArrayLength` | `(arr: T[]) -> number` | Array-Länge | +| `ArrayIsEmpty` | `(arr: T[]) -> boolean` | Prüft ob leer | +| `ArrayGet` | `(arr: T[], index: number) -> T` | Element an Index | +| `ArrayIndexOf` | `(arr: T[], element: T) -> number` | Index des Elements (-1 wenn nicht gefunden) | +| `ArrayContains` | `(arr: T[], element: T) -> boolean` | Prüft ob enthalten | + +### Transformation + +| Funktion | Signatur | Beschreibung | +| --------------- | ----------------------------- | ------------------- | +| `ArrayReverse` | `(arr: T[]) -> T[]` | Array umkehren | +| `ArraySort` | `(arr: number[]) -> number[]` | Numerisch sortieren | +| `ArrayDistinct` | `(arr: T[]) -> T[]` | Duplikate entfernen | + +### Aggregation + +| Funktion | Signatur | Beschreibung | +| -------------- | --------------------------- | ------------ | +| `ArraySum` | `(arr: number[]) -> number` | Summe | +| `ArrayAverage` | `(arr: number[]) -> number` | Durchschnitt | +| `ArrayMin` | `(arr: number[]) -> number` | Minimum | +| `ArrayMax` | `(arr: number[]) -> number` | Maximum | + +### Slicing + +| Funktion | Signatur | Beschreibung | +| ------------ | ----------------------------------------------- | ---------------------------- | +| `ArrayFirst` | `(arr: T[]) -> T` | Erstes Element | +| `ArrayLast` | `(arr: T[]) -> T` | Letztes Element | +| `ArrayTake` | `(arr: T[], n: number) -> T[]` | Erste n Elemente | +| `ArraySkip` | `(arr: T[], n: number) -> T[]` | Überspringt erste n Elemente | +| `ArraySlice` | `(arr: T[], start: number, end: number) -> T[]` | Teilarray | + +### Weitere + +| Funktion | Signatur | Beschreibung | +| ------------ | ----------------------------------------- | ------------------------- | +| `ArrayJoin` | `(arr: T[], separator: string) -> string` | Array zu String | +| `ArrayCount` | `(arr: T[], element: T) -> number` | Häufigkeit eines Elements | + +## Statistics Builtins + +### Zentrale Tendenz + +| Funktion | Signatur | Beschreibung | +| ----------------- | --------------------------- | -------------------------- | +| `CalculateMean` | `(arr: number[]) -> number` | Arithmetisches Mittel | +| `CalculateMedian` | `(arr: number[]) -> number` | Median | +| `CalculateMode` | `(arr: number[]) -> number` | Modus (häufigstes Element) | + +### Streuung + +| Funktion | Signatur | Beschreibung | +| ---------------------------- | ----------------------------------------------- | ---------------------- | +| `CalculateVariance` | `(arr: number[]) -> number` | Varianz | +| `CalculateStandardDeviation` | `(arr: number[]) -> number` | Standardabweichung | +| `CalculateRange` | `(arr: number[]) -> number` | Spannweite (Max - Min) | +| `CalculatePercentile` | `(arr: number[], percentile: number) -> number` | Perzentil berechnen | + +### Korrelation & Regression + +| Funktion | Signatur | Beschreibung | +| ---------------------- | ------------------------------------------------ | ------------------------------------- | +| `CalculateCorrelation` | `(x: number[], y: number[]) -> number` | Korrelationskoeffizient | +| `LinearRegression` | `(x: number[], y: number[]) -> (number, number)` | Lineare Regression (slope, intercept) | + +## Time Builtins + +### Aktuelle Zeit + +| Funktion | Signatur | Beschreibung | +| ---------------------- | ---------------------------- | ---------------------------- | +| `GetCurrentTime` | `() -> number` | Unix Timestamp (Sekunden) | +| `GetCurrentDate` | `() -> string` | Aktuelles Datum (YYYY-MM-DD) | +| `GetCurrentTimeString` | `() -> string` | Aktuelle Zeit (HH:MM:SS) | +| `GetCurrentDateTime` | `() -> string` | Datum und Zeit | +| `FormatDateTime` | `(format: string) -> string` | Formatierte Zeit | + +### Datum-Komponenten + +| Funktion | Signatur | Beschreibung | +| -------------- | -------------- | ----------------------- | +| `GetYear` | `() -> number` | Aktuelles Jahr | +| `GetMonth` | `() -> number` | Aktueller Monat (1-12) | +| `GetDay` | `() -> number` | Aktueller Tag (1-31) | +| `GetHour` | `() -> number` | Aktuelle Stunde (0-23) | +| `GetMinute` | `() -> number` | Aktuelle Minute (0-59) | +| `GetSecond` | `() -> number` | Aktuelle Sekunde (0-59) | +| `GetDayOfWeek` | `() -> number` | Wochentag (0=Sonntag) | +| `GetDayOfYear` | `() -> number` | Tag im Jahr (1-366) | + +### Datum-Berechnungen + +| Funktion | Signatur | Beschreibung | +| ---------------- | ----------------------------------------- | ---------------- | +| `IsLeapYear` | `(year: number) -> boolean` | Prüft Schaltjahr | +| `GetDaysInMonth` | `(year: number, month: number) -> number` | Tage im Monat | + +## System Builtins + +### System-Informationen + +| Funktion | Signatur | Beschreibung | +| --------------------- | -------------- | --------------------- | +| `GetCurrentDirectory` | `() -> string` | Aktuelles Verzeichnis | +| `GetOperatingSystem` | `() -> string` | Betriebssystem | +| `GetArchitecture` | `() -> string` | CPU-Architektur | +| `GetCpuCount` | `() -> number` | Anzahl CPU-Kerne | +| `GetHostname` | `() -> string` | Hostname | +| `GetUsername` | `() -> string` | Benutzername | +| `GetHomeDirectory` | `() -> string` | Home-Verzeichnis | +| `GetTempDirectory` | `() -> string` | Temp-Verzeichnis | + +### Umgebungsvariablen + +| Funktion | Signatur | Beschreibung | +| ----------- | --------------------------------------- | ------------------------ | +| `GetEnvVar` | `(name: string) -> string` | Umgebungsvariable lesen | +| `SetEnvVar` | `(name: string, value: string) -> void` | Umgebungsvariable setzen | + +### Prozess + +| Funktion | Signatur | Beschreibung | +| --------- | ------------------------ | ----------------------- | +| `GetArgs` | `() -> string[]` | Kommandozeilenargumente | +| `Exit` | `(code: number) -> void` | Programm beenden | + +## File Builtins + +### Datei-Operationen + +| Funktion | Signatur | Beschreibung | +| ------------ | ----------------------------------------- | ----------------- | +| `ReadFile` | `(path: string) -> string` | Datei lesen | +| `WriteFile` | `(path: string, content: string) -> void` | Datei schreiben | +| `AppendFile` | `(path: string, content: string) -> void` | An Datei anhängen | +| `DeleteFile` | `(path: string) -> void` | Datei löschen | +| `CopyFile` | `(from: string, to: string) -> void` | Datei kopieren | +| `RenameFile` | `(from: string, to: string) -> void` | Datei umbenennen | + +### Datei-Informationen + +| Funktion | Signatur | Beschreibung | +| -------------------- | --------------------------- | --------------------------------- | +| `FileExists` | `(path: string) -> boolean` | Prüft ob Datei existiert | +| `IsFile` | `(path: string) -> boolean` | Prüft ob Pfad eine Datei ist | +| `IsDirectory` | `(path: string) -> boolean` | Prüft ob Pfad ein Verzeichnis ist | +| `GetFileSize` | `(path: string) -> number` | Dateigröße in Bytes | +| `GetFileExtension` | `(path: string) -> string` | Dateiendung | +| `GetFileName` | `(path: string) -> string` | Dateiname | +| `GetParentDirectory` | `(path: string) -> string` | Übergeordnetes Verzeichnis | + +### Verzeichnis-Operationen + +| Funktion | Signatur | Beschreibung | +| ----------------- | ---------------------------- | --------------------------- | +| `CreateDirectory` | `(path: string) -> void` | Verzeichnis erstellen | +| `ListDirectory` | `(path: string) -> string[]` | Verzeichnisinhalt auflisten | + +## Validation Builtins + +### Format-Validierung + +| Funktion | Signatur | Beschreibung | +| -------------------- | ---------------------------- | ------------------------- | +| `IsValidEmail` | `(email: string) -> boolean` | E-Mail-Validierung | +| `IsValidUrl` | `(url: string) -> boolean` | URL-Validierung | +| `IsValidPhoneNumber` | `(phone: string) -> boolean` | Telefonnummer-Validierung | + +### Zeichen-Prüfungen + +| Funktion | Signatur | Beschreibung | +| ---------------- | ------------------------ | ------------------------- | +| `IsAlphanumeric` | `(s: string) -> boolean` | Nur Buchstaben und Zahlen | +| `IsAlphabetic` | `(s: string) -> boolean` | Nur Buchstaben | +| `IsNumeric` | `(s: string) -> boolean` | Nur Zahlen | +| `IsLowercase` | `(s: string) -> boolean` | Nur Kleinbuchstaben | +| `IsUppercase` | `(s: string) -> boolean` | Nur Großbuchstaben | + +### Weitere Validierungen + +| Funktion | Signatur | Beschreibung | +| ---------------- | ------------------------------------------------------ | ------------------- | +| `IsInRange` | `(value: number, min: number, max: number) -> boolean` | Wertebereich prüfen | +| `MatchesPattern` | `(text: string, pattern: string) -> boolean` | Regex-Match | + +## Hashing Builtins + +### Hash-Funktionen + +| Funktion | Signatur | Beschreibung | +| -------------- | -------------------------- | ------------------ | +| `HashString` | `(s: string) -> number` | String hashen | +| `HashNumber` | `(n: number) -> number` | Number hashen | +| `SimpleRandom` | `(seed: number) -> number` | Pseudo-Zufallszahl | + +### String-Analyse + +| Funktion | Signatur | Beschreibung | +| ------------------ | ------------------------------------------- | ------------------- | +| `AreAnagrams` | `(s1: string, s2: string) -> boolean` | Prüft Anagramme | +| `IsPalindrome` | `(s: string) -> boolean` | Prüft Palindrom | +| `CountOccurrences` | `(text: string, pattern: string) -> number` | Vorkommen zählen | +| `RemoveDuplicates` | `(s: string) -> string` | Duplikate entfernen | +| `UniqueCharacters` | `(s: string) -> string` | Eindeutige Zeichen | +| `ReverseWords` | `(s: string) -> string` | Wörter umkehren | +| `TitleCase` | `(s: string) -> string` | Title Case Format | + +## DeepMind Builtins (Higher-Order Functions) + +### Kontrollfluss + +| Funktion | Signatur | Beschreibung | +| ------------------- | ------------------------------------------------------------- | ------------------------ | +| `RepeatAction` | `(times: number, action: () -> void) -> void` | Aktion n-mal wiederholen | +| `DelayedSuggestion` | `(action: () -> void, delay: number) -> void` | Verzögerte Ausführung | +| `IfTranced` | `(cond: boolean, then: () -> void, else: () -> void) -> void` | Bedingte Ausführung | + +### Schleifen + +| Funktion | Signatur | Beschreibung | +| ------------- | -------------------------------------------------------- | ----------------------------- | +| `RepeatUntil` | `(action: () -> void, condition: () -> boolean) -> void` | Wiederhole bis Bedingung wahr | +| `RepeatWhile` | `(condition: () -> boolean, action: () -> void) -> void` | Wiederhole solange wahr | + +### Funktionskomposition + +| Funktion | Signatur | Beschreibung | +| --------- | ------------------------------------ | ---------------------------- | +| `Compose` | `(f: B -> C, g: A -> B) -> (A -> C)` | Funktionskomposition f(g(x)) | +| `Pipe` | `(f: A -> B, g: B -> C) -> (A -> C)` | Funktions-Pipeline g(f(x)) | + +### Fehlerbehandlung + +| Funktion | Signatur | Beschreibung | +| ----------------- | ----------------------------------------------------------- | ------------ | +| `TryOrAwaken` | `(try: () -> void, catch: (error: string) -> void) -> void` | Try-Catch | +| `EnsureAwakening` | `(main: () -> void, cleanup: () -> void) -> void` | Try-Finally | + +### Weitere + +| Funktion | Signatur | Beschreibung | +| -------------------- | ----------------------------------- | ------------------------------ | +| `SequentialTrance` | `(actions: (() -> void)[]) -> void` | Aktionen sequentiell ausführen | +| `MeasureTranceDepth` | `(action: () -> void) -> number` | Ausführungszeit messen | +| `Memoize` | `(f: A -> R) -> (A -> R)` | Funktion mit Caching | + +## Verwendungshinweise + +### Namenskonventionen + +- **PascalCase** für Funktionsnamen (z.B. `CalculateMean`, `ToUpper`) +- **Case-Insensitive** Matching beim Aufruf +- **Typ-Parameter** `T` für generische Funktionen + +### Fehlerbehandlung + +- Funktionen die fehlschlagen können werfen Runtime-Errors +- Nutze `TryOrAwaken` für Fehlerbehandlung +- Validiere Eingaben mit Validation-Builtins + +### Performance + +- Array-Operationen erstellen neue Arrays (immutabel) +- Nutze `Memoize` für teure Berechnungen +- `MeasureTranceDepth` für Performance-Profiling + +## Siehe auch + +- [Detaillierte Array-Funktionen](./array-functions) +- [Detaillierte String-Funktionen](./string-functions) +- [Detaillierte Math-Funktionen](./math-functions) +- [CLI Builtin-Befehl](../cli/commands#builtins) diff --git a/HypnoScript.Dokumentation/docs/builtins/array-functions.md b/hypnoscript-docs/docs/builtins/array-functions.md similarity index 95% rename from HypnoScript.Dokumentation/docs/builtins/array-functions.md rename to hypnoscript-docs/docs/builtins/array-functions.md index ce3cf64..890e037 100644 --- a/HypnoScript.Dokumentation/docs/builtins/array-functions.md +++ b/hypnoscript-docs/docs/builtins/array-functions.md @@ -4,6 +4,14 @@ sidebar_position: 2 # Array-Funktionen +:::tip Vollständige Referenz +Siehe [Builtin-Funktionen Vollständige Referenz](./_complete-reference#array-builtins) für die **aktuelle, vollständige Dokumentation** aller Array-Funktionen mit korrekten Funktionsnamen. +::: + +:::warning Hinweis +Diese Seite enthält teilweise veraltete Funktionsnamen. Die korrekte Referenz finden Sie in der [Vollständigen Referenz](./_complete-reference#array-builtins). +::: + HypnoScript bietet umfangreiche Array-Funktionen für die Arbeit mit Listen und Sammlungen von Daten. ## Grundlegende Array-Operationen @@ -72,13 +80,13 @@ observe reversed; // [5, 4, 3, 2, 1] ## Array-Analyse -### SumArray(arr) +### ArraySum(arr) Berechnet die Summe aller numerischen Elemente. ```hyp induce numbers = [1, 2, 3, 4, 5]; -induce sum = SumArray(numbers); +induce sum = ArraySum(numbers); observe "Summe: " + sum; // 15 ``` diff --git a/hypnoscript-docs/docs/builtins/deepmind-functions.md b/hypnoscript-docs/docs/builtins/deepmind-functions.md new file mode 100644 index 0000000..b3f4fce --- /dev/null +++ b/hypnoscript-docs/docs/builtins/deepmind-functions.md @@ -0,0 +1,218 @@ +--- +description: Höhere Kontrollfluss- und Kompositions-Builtins für HypnoScript. +--- + +# DeepMind-Funktionen + +Die DeepMind-Builtins erweitern HypnoScript um mächtige Kontrollfluss- und Functional-Programming-Patterns. Sie +arbeiten Hand in Hand mit `suggestion`-Blöcken und erlauben es, Schleifen, Verzögerungen, Fehlerbehandlung und +Funktionskomposition deklarativ auszudrücken. + +## Überblick + +| Funktion | Rückgabewert | Kurzbeschreibung | +| -------------------- | ------------ | ------------------------------------------ | +| `RepeatAction` | `void` | Aktion eine feste Anzahl an Wiederholungen | +| `DelayedSuggestion` | `void` | Aktion nach Millisekunden-Verzögerung | +| `IfTranced` | `void` | Bedingte Ausführung zweier Vorschläge | +| `RepeatUntil` | `void` | Wiederhole Aktion bis Bedingung `true` | +| `RepeatWhile` | `void` | Wiederhole solange Bedingung `true` | +| `SequentialTrance` | `void` | Liste von Aktionen seriell ausführen | +| `Compose` / `Pipe` | `suggestion` | Funktionen kombinieren | +| `TryOrAwaken` | `void` | Fehlerpfad behandeln | +| `EnsureAwakening` | `void` | Cleanup garantiert ausführen | +| `MeasureTranceDepth` | `number` | Laufzeit in Millisekunden messen | +| `Memoize` | `suggestion` | Funktionsresultate zwischenspeichern | + +:::tip Namenskonventionen +Alle DeepMind-Builtins verwenden PascalCase (`RepeatAction`) und akzeptieren `suggestion()`-Blöcke als Parameter. +Die Signaturen sind case-insensitive, so dass `repeataction` ebenfalls funktioniert. +::: + +## Wiederholung & Timing + +### RepeatAction(times, action) + +- **Signatur:** `(times: number, action: () -> void) -> void` +- **Beschreibung:** Führt `action` `times`-mal aus. Negative Werte werden ignoriert. + +```hyp +RepeatAction(3, suggestion() { + observe "Affirmation"; +}); +``` + +### DelayedSuggestion(action, delayMs) + +- **Signatur:** `(action: () -> void, delay: number) -> void` +- **Beschreibung:** Führt `action` nach `delay` Millisekunden aus. Die Ausführung blockiert bis zum Ablauf der Zeit. + +```hyp +DelayedSuggestion(suggestion() { + observe "Willkommen nach 2 Sekunden"; +}, 2000); +``` + +## Bedingte Ausführung + +### IfTranced(condition, thenAction, elseAction) + +- **Signatur:** `(condition: boolean, then: () -> void, otherwise: () -> void) -> void` +- **Beschreibung:** Evaluierte Bedingung; bei `true` wird `then`, sonst `otherwise` ausgeführt. + +```hyp +IfTranced(audienceSize > 10, + suggestion() { observe "Großgruppe"; }, + suggestion() { observe "Intime Sitzung"; } +); +``` + +## Komposition & Pipelines + +### Compose(f, g) + +- **Signatur:** `(f: (B) -> C, g: (A) -> B) -> (A -> C)` +- **Beschreibung:** Erst `g`, dann `f`. Nützlich für wiederverwendbare Datenpipelines. + +```hyp +suggestion double(x: number): number { awaken x * 2; } +suggestion addTen(x: number): number { awaken x + 10; } + +induce transformer = Compose(double, addTen); +induce result: number = transformer(5); // 30 +``` + +### Pipe(f, g) + +- **Signatur:** `(f: (A) -> B, g: (B) -> C) -> (A -> C)` +- **Beschreibung:** Umgekehrte Reihenfolge: zuerst `f`, danach `g`. + +```hyp +induce pipeline = Pipe(double, addTen); +observe pipeline(5); // 20 +``` + +## Schleifensteuerung + +### RepeatUntil(action, condition) + +- **Signatur:** `(action: () -> void, condition: () -> boolean) -> void` +- **Beschreibung:** Führt `action` aus, solange `condition()` `false` liefert. Bedingung wird nach jedem Durchlauf geprüft. + +```hyp +induce counter: number = 0; +RepeatUntil( + suggestion() { counter = counter + 1; }, + suggestion(): boolean { awaken counter >= 5; } +); +``` + +### RepeatWhile(condition, action) + +- **Signatur:** `(condition: () -> boolean, action: () -> void) -> void` +- **Beschreibung:** Prüft `condition()` vor jedem Durchlauf; bei `true` läuft `action`, sonst endet die Schleife. + +```hyp +induce energy: number = 3; +RepeatWhile( + suggestion(): boolean { awaken energy > 0; }, + suggestion() { + observe "Noch Energie: " + energy; + energy = energy - 1; + } +); +``` + +## Sequenzen & Fehlerbehandlung + +### SequentialTrance(actions) + +- **Signatur:** `(actions: (() -> void)[]) -> void` +- **Beschreibung:** Führt eine Liste von `suggestion`-Blöcken nacheinander aus. + +```hyp +SequentialTrance([ + suggestion() { observe "Phase 1"; }, + suggestion() { observe "Phase 2"; }, + suggestion() { observe "Phase 3"; } +]); +``` + +### TryOrAwaken(tryAction, catchAction) + +- **Signatur:** `(try: () -> Result, catch: (error: string) -> void) -> void` +- **Beschreibung:** Führt `try` aus und ruft bei Fehlern `catch` mit der Fehlermeldung auf. + +```hyp +TryOrAwaken( + suggestion(): Result { + if (audienceSize < 0) { + awaken Err("Negative Audience"); + } + observe "Session startet"; + awaken Ok(()); + }, + suggestion(error: string) { + observe "Fehler: " + error; + } +); +``` + +### EnsureAwakening(mainAction, cleanup) + +- **Signatur:** `(main: () -> void, cleanup: () -> void) -> void` +- **Beschreibung:** Führt `main` aus und garantiert, dass `cleanup` anschließend aufgerufen wird. + +```hyp +EnsureAwakening( + suggestion() { + observe "Datei öffnen"; + }, + suggestion() { + observe "Datei schließen"; + } +); +``` + +## Messung & Memoisierung + +### MeasureTranceDepth(action) + +- **Signatur:** `(action: () -> void) -> number` +- **Beschreibung:** Führt `action` aus und gibt die Dauer in Millisekunden zurück. + +```hyp +induce duration: number = MeasureTranceDepth(suggestion() { + RepeatAction(1000, suggestion() { observe "Tick"; }); +}); +observe "Laufzeit: " + duration + " ms"; +``` + +### Memoize(f) + +- **Signatur:** `(f: (A) -> R) -> (A -> R)` +- **Beschreibung:** Liefert eine Wrapper-Funktion. In der aktuellen Runtime-Version wird das Ergebnis nicht dauerhaft + zwischengespeichert, aber das Interface bleibt stabil für zukünftige Optimierungen. + +```hyp +suggestion square(x: number): number { awaken x * x; } +induce memoSquare = Memoize(square); + +observe memoSquare(4); // 16 +observe memoSquare(4); // 16 (zukünftig aus Cache) +``` + +## Tipps für den Einsatz + +- `RepeatAction`, `RepeatUntil` und `RepeatWhile` blockieren synchron; nutze `DelayedSuggestion` für einfache + Zeitsteuerung. +- Kombiniere `Compose` und `Pipe` mit Array- oder String-Builtins, um filter-map-reduce-Ketten lesbar zu halten. +- `TryOrAwaken` erwartet einen `Result`-ähnlichen Rückgabewert. Gib `Ok(())` für Erfolg und `Err("Message")` für Fehler + zurück. +- `MeasureTranceDepth` eignet sich für schnelle Performance-Messungen ohne zusätzliches Werkzeug. + +## Siehe auch + +- [Builtin-Übersicht](./overview) +- [Vollständige Referenz – DeepMind](./_complete-reference#deepmind-builtins-higher-order-functions) +- [CLI Builtins anzeigen](../cli/commands#builtins) diff --git a/HypnoScript.Dokumentation/docs/builtins/dictionary-functions.md b/hypnoscript-docs/docs/builtins/dictionary-functions.md similarity index 100% rename from HypnoScript.Dokumentation/docs/builtins/dictionary-functions.md rename to hypnoscript-docs/docs/builtins/dictionary-functions.md diff --git a/HypnoScript.Dokumentation/docs/builtins/file-functions.md b/hypnoscript-docs/docs/builtins/file-functions.md similarity index 100% rename from HypnoScript.Dokumentation/docs/builtins/file-functions.md rename to hypnoscript-docs/docs/builtins/file-functions.md diff --git a/HypnoScript.Dokumentation/docs/builtins/hashing-encoding.md b/hypnoscript-docs/docs/builtins/hashing-encoding.md similarity index 100% rename from HypnoScript.Dokumentation/docs/builtins/hashing-encoding.md rename to hypnoscript-docs/docs/builtins/hashing-encoding.md diff --git a/HypnoScript.Dokumentation/docs/builtins/hypnotic-functions.md b/hypnoscript-docs/docs/builtins/hypnotic-functions.md similarity index 100% rename from HypnoScript.Dokumentation/docs/builtins/hypnotic-functions.md rename to hypnoscript-docs/docs/builtins/hypnotic-functions.md diff --git a/HypnoScript.Dokumentation/docs/builtins/math-functions.md b/hypnoscript-docs/docs/builtins/math-functions.md similarity index 74% rename from HypnoScript.Dokumentation/docs/builtins/math-functions.md rename to hypnoscript-docs/docs/builtins/math-functions.md index 7cb8b47..d9f07f6 100644 --- a/HypnoScript.Dokumentation/docs/builtins/math-functions.md +++ b/hypnoscript-docs/docs/builtins/math-functions.md @@ -4,204 +4,278 @@ sidebar_position: 4 # Mathematische Funktionen -HypnoScript bietet umfangreiche mathematische Funktionen für Berechnungen, Statistik und wissenschaftliche Anwendungen. +HypnoScript bietet mathematische Funktionen für Berechnungen, Trigonometrie und Zahlentheorie. -## Grundlegende Mathematik +## Verfügbare Funktionen -### Abs(x) +Die folgenden Funktionen sind in der `MathBuiltins`-Bibliothek verfügbar: -Gibt den absoluten Wert einer Zahl zurück. +### Trigonometrische Funktionen + +#### sin(x: number): number + +Berechnet den Sinus (x in Radiant). ```hyp -induce abs1 = Abs(-5); // 5 -induce abs2 = Abs(3.14); // 3.14 -induce abs3 = Abs(0); // 0 +Focus { + induce result: number = sin(0); // 0 + observe "sin(0) = " + result; +} Relax ``` -### Sign(x) +#### cos(x: number): number -Gibt das Vorzeichen einer Zahl zurück (-1, 0, 1). +Berechnet den Kosinus (x in Radiant). ```hyp -induce sign1 = Sign(-10); // -1 -induce sign2 = Sign(0); // 0 -induce sign3 = Sign(42); // 1 +Focus { + induce result: number = cos(0); // 1 + observe "cos(0) = " + result; +} Relax ``` -### Floor(x) +#### tan(x: number): number -Rundet eine Zahl ab. +Berechnet den Tangens (x in Radiant). ```hyp -induce floor1 = Floor(3.7); // 3 -induce floor2 = Floor(-3.7); // -4 -induce floor3 = Floor(5); // 5 +Focus { + induce result: number = tan(0); // 0 + observe "tan(0) = " + result; +} Relax ``` -### Ceiling(x) +### Wurzel- und Potenzfunktionen + +#### sqrt(x: number): number -Rundet eine Zahl auf. +Berechnet die Quadratwurzel. ```hyp -induce ceiling1 = Ceiling(3.2); // 4 -induce ceiling2 = Ceiling(-3.2); // -3 -induce ceiling3 = Ceiling(5); // 5 +Focus { + induce result: number = sqrt(16); // 4 + observe "sqrt(16) = " + result; +} Relax ``` -### Round(x, decimals) +#### pow(base: number, exponent: number): number -Rundet eine Zahl auf eine bestimmte Anzahl Dezimalstellen. +Berechnet eine Potenz. ```hyp -induce round1 = Round(3.14159, 2); // 3.14 -induce round2 = Round(3.14159, 0); // 3 -induce round3 = Round(3.5, 0); // 4 +Focus { + induce result: number = pow(2, 3); // 8 + observe "2^3 = " + result; +} Relax ``` -### Min(x, y) +### Logarithmen + +#### log(x: number): number -Gibt den kleineren von zwei Werten zurück. +Berechnet den natürlichen Logarithmus (ln). ```hyp -induce min1 = Min(5, 3); // 3 -induce min2 = Min(-10, 5); // -10 -induce min3 = Min(3.14, 3.15); // 3.14 +Focus { + induce result: number = log(2.718281828); // ~1 + observe "ln(e) = " + result; +} Relax ``` -### Max(x, y) +#### log10(x: number): number -Gibt den größeren von zwei Werten zurück. +Berechnet den Logarithmus zur Basis 10. ```hyp -induce max1 = Max(5, 3); // 5 -induce max2 = Max(-10, 5); // 5 -induce max3 = Max(3.14, 3.15); // 3.15 +Focus { + induce result: number = log10(100); // 2 + observe "log10(100) = " + result; +} Relax ``` -### Clamp(value, min, max) +### Rundungsfunktionen -Begrenzt einen Wert auf einen Bereich. +#### abs(x: number): number + +Gibt den absoluten Wert zurück. ```hyp -induce clamp1 = Clamp(15, 0, 10); // 10 -induce clamp2 = Clamp(-5, 0, 10); // 0 -induce clamp3 = Clamp(5, 0, 10); // 5 +Focus { + induce result: number = abs(-5); // 5 + observe "abs(-5) = " + result; +} Relax ``` -## Potenzen und Wurzeln +#### floor(x: number): number -### Pow(base, exponent) +Rundet ab. -Berechnet eine Potenz. +```hyp +Focus { + induce result: number = floor(3.7); // 3 + observe "floor(3.7) = " + result; +} Relax +``` + +#### ceil(x: number): number + +Rundet auf. ```hyp -induce pow1 = Pow(2, 3); // 8 -induce pow2 = Pow(5, 2); // 25 -induce pow3 = Pow(2, 0.5); // 1.4142135623730951 +Focus { + induce result: number = ceil(3.2); // 4 + observe "ceil(3.2) = " + result; +} Relax ``` -### Sqrt(x) +#### round(x: number): number -Berechnet die Quadratwurzel. +Rundet zur nächsten ganzen Zahl. ```hyp -induce sqrt1 = Sqrt(16); // 4 -induce sqrt2 = Sqrt(2); // 1.4142135623730951 -induce sqrt3 = Sqrt(0); // 0 +Focus { + induce result: number = round(3.5); // 4 + observe "round(3.5) = " + result; +} Relax ``` -### Cbrt(x) +### Min/Max -Berechnet die Kubikwurzel. +#### min(a: number, b: number): number + +Gibt den kleineren Wert zurück. ```hyp -induce cbrt1 = Cbrt(27); // 3 -induce cbrt2 = Cbrt(8); // 2 -induce cbrt3 = Cbrt(-8); // -2 +Focus { + induce result: number = min(5, 3); // 3 + observe "min(5, 3) = " + result; +} Relax ``` -### Root(x, n) +#### max(a: number, b: number): number -Berechnet die n-te Wurzel. +Gibt den größeren Wert zurück. ```hyp -induce root1 = Root(16, 4); // 2 -induce root2 = Root(32, 5); // 2 -induce root3 = Root(100, 2); // 10 +Focus { + induce result: number = max(5, 3); // 5 + observe "max(5, 3) = " + result; +} Relax ``` -## Trigonometrie +### Erweiterte Funktionen -### Sin(x) +#### factorial(n: number): number -Berechnet den Sinus (Radiant). +Berechnet die Fakultät. ```hyp -induce sin1 = Sin(0); // 0 -induce sin2 = Sin(PI / 2); // 1 -induce sin3 = Sin(PI); // 0 +Focus { + induce result: number = factorial(5); // 120 + observe "5! = " + result; +} Relax ``` -### Cos(x) +#### gcd(a: number, b: number): number -Berechnet den Kosinus (Radiant). +Berechnet den größten gemeinsamen Teiler. ```hyp -induce cos1 = Cos(0); // 1 -induce cos2 = Cos(PI / 2); // 0 -induce cos3 = Cos(PI); // -1 +Focus { + induce result: number = gcd(48, 18); // 6 + observe "gcd(48, 18) = " + result; +} Relax ``` -### Tan(x) +#### lcm(a: number, b: number): number -Berechnet den Tangens (Radiant). +Berechnet das kleinste gemeinsame Vielfache. ```hyp -induce tan1 = Tan(0); // 0 -induce tan2 = Tan(PI / 4); // 1 -induce tan3 = Tan(PI / 2); // Unendlich +Focus { + induce result: number = lcm(12, 18); // 36 + observe "lcm(12, 18) = " + result; +} Relax ``` -### Asin(x) +#### is_prime(n: number): boolean -Berechnet den Arkussinus. +Prüft, ob eine Zahl eine Primzahl ist. ```hyp -induce asin1 = Asin(0); // 0 -induce asin2 = Asin(1); // PI / 2 -induce asin3 = Asin(-1); // -PI / 2 +Focus { + induce result: boolean = is_prime(7); // true + observe "7 ist Primzahl: " + result; +} Relax ``` -### Acos(x) +#### fibonacci(n: number): number -Berechnet den Arkuskosinus. +Berechnet die n-te Fibonacci-Zahl. ```hyp -induce acos1 = Acos(1); // 0 -induce acos2 = Acos(0); // PI / 2 -induce acos3 = Acos(-1); // PI +Focus { + induce result: number = fibonacci(10); // 55 + observe "fibonacci(10) = " + result; +} Relax ``` -### Atan(x) +#### clamp(value: number, min: number, max: number): number -Berechnet den Arkustangens. +Begrenzt einen Wert auf einen Bereich. ```hyp -induce atan1 = Atan(0); // 0 -induce atan2 = Atan(1); // PI / 4 -induce atan3 = Atan(-1); // -PI / 4 +Focus { + induce result: number = clamp(15, 0, 10); // 10 + observe "clamp(15, 0, 10) = " + result; +} Relax ``` -### Atan2(y, x) - -Berechnet den Arkustangens mit Quadrantenbestimmung. +## Vollständiges Beispiel ```hyp -induce atan2_1 = Atan2(1, 1); // PI / 4 -induce atan2_2 = Atan2(1, -1); // 3 * PI / 4 -induce atan2_3 = Atan2(-1, -1); // -3 * PI / 4 +Focus { + entrance { + observe "=== Mathematische Funktionen Demo ==="; + + // Trigonometrie + induce angle: number = 0; + observe "sin(0) = " + sin(angle); + observe "cos(0) = " + cos(angle); + + // Wurzeln und Potenzen + observe "sqrt(16) = " + sqrt(16); + observe "pow(2, 10) = " + pow(2, 10); + + // Rundung + induce pi: number = 3.14159; + observe "floor(pi) = " + floor(pi); + observe "ceil(pi) = " + ceil(pi); + observe "round(pi) = " + round(pi); + + // Min/Max + observe "min(5, 10) = " + min(5, 10); + observe "max(5, 10) = " + max(5, 10); + + // Erweiterte Funktionen + observe "factorial(5) = " + factorial(5); + observe "gcd(48, 18) = " + gcd(48, 18); + observe "fibonacci(10) = " + fibonacci(10); + observe "is_prime(13): " + is_prime(13); + } +} Relax ``` +## Hinweise + +- Alle Winkelfunktionen (sin, cos, tan) erwarten Radiant als Eingabe +- Die Funktionen sind direkt verfügbar und müssen nicht importiert werden +- Typ-Konvertierungen erfolgen automatisch zwischen ganzen Zahlen und Fließkommazahlen + induce atan2_2 = Atan2(1, -1); // 3 _ PI / 4 + induce atan2_3 = Atan2(-1, -1); // -3 _ PI / 4 + +```` + ### DegreesToRadians(degrees) Konvertiert Grad in Radiant. @@ -210,7 +284,7 @@ Konvertiert Grad in Radiant. induce rad1 = DegreesToRadians(0); // 0 induce rad2 = DegreesToRadians(90); // PI / 2 induce rad3 = DegreesToRadians(180); // PI -``` +```` ### RadiansToDegrees(radians) diff --git a/HypnoScript.Dokumentation/docs/builtins/network-functions.md b/hypnoscript-docs/docs/builtins/network-functions.md similarity index 100% rename from HypnoScript.Dokumentation/docs/builtins/network-functions.md rename to hypnoscript-docs/docs/builtins/network-functions.md diff --git a/hypnoscript-docs/docs/builtins/overview.md b/hypnoscript-docs/docs/builtins/overview.md new file mode 100644 index 0000000..1d7788f --- /dev/null +++ b/hypnoscript-docs/docs/builtins/overview.md @@ -0,0 +1,329 @@ +--- +sidebar_position: 1 +--- + +# Builtin-Funktionen Übersicht + +HypnoScript bietet eine umfassende Standardbibliothek mit über **110 eingebauten Funktionen** in der Rust-Edition. Diese Funktionen sind direkt in der Sprache verfügbar und erfordern keine zusätzlichen Imports. + +## Kategorien + +### 🧠 Core & Hypnotische Funktionen + +Grundlegende I/O, Konvertierung und hypnotische Spezialfunktionen. + +| Funktion | Beschreibung | Beispiel | +| ------------------------- | ----------------------------------- | ----------------------------------- | +| `observe(text)` | Standard-Ausgabe mit Zeilenumbruch | `observe "Hallo Welt";` | +| `whisper(text)` | Ausgabe ohne Zeilenumbruch | `whisper "Teil1"; whisper "Teil2";` | +| `command(text)` | Imperative Ausgabe (Großbuchstaben) | `command "Wichtig!";` | +| `drift(ms)` | Pause/Sleep in Millisekunden | `drift(2000);` | +| `DeepTrance(duration)` | Tiefe Trance-Induktion | `DeepTrance(5000);` | +| `HypnoticCountdown(from)` | Hypnotischer Countdown | `HypnoticCountdown(10);` | +| `TranceInduction(name)` | Vollständige Trance-Induktion | `TranceInduction("Max");` | +| `ToInt(value)` | Zu Integer konvertieren | `ToInt(3.14)` → `3` | +| `ToString(value)` | Zu String konvertieren | `ToString(42)` → `"42"` | +| `ToBoolean(value)` | Zu Boolean konvertieren | `ToBoolean("true")` → `true` | + +### 🔢 Math-Funktionen + +Umfassende mathematische Operationen und Berechnungen. + +| Kategorie | Funktionen | +| ---------------------- | ------------------------------------------------- | +| **Trigonometrie** | `Sin`, `Cos`, `Tan` | +| **Wurzeln & Potenzen** | `Sqrt`, `Pow` | +| **Logarithmen** | `Log` (ln), `Log10` | +| **Rundung** | `Abs`, `Floor`, `Ceil`, `Round`, `Clamp` | +| **Min/Max** | `Min`, `Max` | +| **Zahlentheorie** | `Factorial`, `Gcd`, `Lcm`, `IsPrime`, `Fibonacci` | + +**Beispiel:** + +```hyp +induce result: number = Sqrt(16); // 4.0 +induce isPrime: boolean = IsPrime(17); // true +induce fib: number = Fibonacci(10); // 55 +``` + +### 📝 String-Funktionen + +Funktionen für String-Manipulation und -Analyse. + +| Kategorie | Funktionen | +| ---------------- | --------------------------------------------------------------- | +| **Basis** | `Length`, `ToUpper`, `ToLower`, `Trim`, `Reverse`, `Capitalize` | +| **Suchen** | `IndexOf`, `Contains`, `StartsWith`, `EndsWith` | +| **Manipulation** | `Replace`, `Split`, `Substring`, `Repeat` | +| **Padding** | `PadLeft`, `PadRight` | +| **Prüfungen** | `IsEmpty`, `IsWhitespace` | + +**Beispiel:** + +```hyp +induce text: string = " Hallo Welt "; +induce cleaned: string = Trim(text); // "Hallo Welt" +induce upper: string = ToUpper(cleaned); // "HALLO WELT" +induce words: string[] = Split(cleaned, " "); // ["Hallo", "Welt"] +``` + +### 📦 Array-Funktionen + +Funktionen für die Arbeit mit Arrays und Listen. + +| Kategorie | Funktionen | +| ------------------ | ------------------------------------------------- | +| **Basis** | `Length`, `IsEmpty`, `Get`, `IndexOf`, `Contains` | +| **Transformation** | `Reverse`, `Sort`, `Distinct` | +| **Aggregation** | `Sum`, `Average`, `Min`, `Max` | +| **Slicing** | `First`, `Last`, `Take`, `Skip`, `Slice` | +| **Weitere** | `Join`, `Count` | + +**Beispiel:** + +```hyp +induce numbers: number[] = [5, 2, 8, 1, 9]; +induce sorted: number[] = Sort(numbers); // [1, 2, 5, 8, 9] +induce sum: number = Sum(numbers); // 25 +induce avg: number = Average(numbers); // 5.0 +``` + +[→ Detaillierte Array-Funktionen](./array-functions) + +### 📊 Statistik-Funktionen + +Funktionen für statistische Berechnungen und Analysen. + +| Kategorie | Funktionen | +| -------------------- | ------------------------------------------------------------------------------------------ | +| **Zentrale Tendenz** | `CalculateMean`, `CalculateMedian`, `CalculateMode` | +| **Streuung** | `CalculateVariance`, `CalculateStandardDeviation`, `CalculateRange`, `CalculatePercentile` | +| **Korrelation** | `CalculateCorrelation`, `LinearRegression` | + +**Beispiel:** + +```hyp +induce data: number[] = [1, 2, 3, 4, 5]; +induce mean: number = CalculateMean(data); // 3.0 +induce stddev: number = CalculateStandardDeviation(data); // 1.58... +``` + +[→ Detaillierte Statistik-Funktionen](./statistics-functions) + +### 🕒 Zeit & Datum + +Funktionen für Zeit- und Datumsverarbeitung. + +| Kategorie | Funktionen | +| ----------------- | -------------------------------------------------------------------- | +| **Aktuelle Zeit** | `GetCurrentTime`, `GetCurrentDate`, `GetCurrentDateTime` | +| **Komponenten** | `GetYear`, `GetMonth`, `GetDay`, `GetHour`, `GetMinute`, `GetSecond` | +| **Berechnungen** | `GetDayOfWeek`, `GetDayOfYear`, `IsLeapYear`, `GetDaysInMonth` | + +**Beispiel:** + +```hyp +induce timestamp: number = GetCurrentTime(); // Unix timestamp +induce date: string = GetCurrentDate(); // "2024-01-15" +induce year: number = GetYear(); // 2024 +``` + +[→ Detaillierte Zeit/Datum-Funktionen](./time-date-functions) + +### 💻 System-Funktionen + +Funktionen für System-Interaktion und -Informationen. + +| Kategorie | Funktionen | +| ----------------- | ------------------------------------------------------------------------------------ | +| **System-Info** | `GetOperatingSystem`, `GetArchitecture`, `GetCpuCount`, `GetHostname`, `GetUsername` | +| **Verzeichnisse** | `GetCurrentDirectory`, `GetHomeDirectory`, `GetTempDirectory` | +| **Umgebung** | `GetEnvVar`, `SetEnvVar`, `GetArgs` | +| **Prozess** | `Exit` | + +**Beispiel:** + +```hyp +induce os: string = GetOperatingSystem(); // "Windows", "Linux", "macOS" +induce cores: number = GetCpuCount(); // 8 +induce home: string = GetHomeDirectory(); // "/home/user" oder "C:\\Users\\user" +``` + +[→ Detaillierte System-Funktionen](./system-functions) + +### 📁 Datei-Funktionen + +Funktionen für Dateisystem-Operationen. + +| Kategorie | Funktionen | +| ------------------- | ---------------------------------------------------------------------- | +| **Lesen/Schreiben** | `ReadFile`, `WriteFile`, `AppendFile` | +| **Verwaltung** | `DeleteFile`, `CopyFile`, `RenameFile` | +| **Prüfungen** | `FileExists`, `IsFile`, `IsDirectory` | +| **Informationen** | `GetFileSize`, `GetFileExtension`, `GetFileName`, `GetParentDirectory` | +| **Verzeichnisse** | `CreateDirectory`, `ListDirectory` | + +**Beispiel:** + +```hyp +if (FileExists("config.txt")) { + induce content: string = ReadFile("config.txt"); + observe "Config: " + content; +} else { + WriteFile("config.txt", "default config"); +} +``` + +[→ Detaillierte Datei-Funktionen](./file-functions) + +### ✅ Validierung + +Funktionen für Datenvalidierung. + +| Kategorie | Funktionen | +| ----------- | --------------------------------------------------------------------------- | +| **Format** | `IsValidEmail`, `IsValidUrl`, `IsValidPhoneNumber` | +| **Zeichen** | `IsAlphanumeric`, `IsAlphabetic`, `IsNumeric`, `IsLowercase`, `IsUppercase` | +| **Weitere** | `IsInRange`, `MatchesPattern` | + +**Beispiel:** + +```hyp +induce email: string = "user@example.com"; +if (IsValidEmail(email)) { + observe "Gültige E-Mail!"; +} +``` + +[→ Detaillierte Validierung-Funktionen](./validation-functions) + +### 🔐 Hashing & String-Analyse + +Funktionen für Hashing und erweiterte String-Operationen. + +| Kategorie | Funktionen | +| ------------------ | ------------------------------------------------------------------- | +| **Hashing** | `HashString`, `HashNumber`, `SimpleRandom` | +| **Analyse** | `AreAnagrams`, `IsPalindrome`, `CountOccurrences` | +| **Transformation** | `RemoveDuplicates`, `UniqueCharacters`, `ReverseWords`, `TitleCase` | + +**Beispiel:** + +```hyp +induce hash: number = HashString("password"); +induce isPalin: boolean = IsPalindrome("anna"); // true +induce titleText: string = TitleCase("hello world"); // "Hello World" +``` + +[→ Detaillierte Hashing-Funktionen](./hashing-encoding) + +### 🧠 DeepMind (Higher-Order Functions) + +Erweiterte funktionale Programmierung und Kontrollfluss. + +| Kategorie | Funktionen | +| -------------------- | ---------------------------------------------------------------- | +| **Schleifen** | `RepeatAction`, `RepeatUntil`, `RepeatWhile` | +| **Verzögerung** | `DelayedSuggestion` | +| **Komposition** | `Compose`, `Pipe` | +| **Fehlerbehandlung** | `TryOrAwaken`, `EnsureAwakening` | +| **Weitere** | `IfTranced`, `SequentialTrance`, `MeasureTranceDepth`, `Memoize` | + +**Beispiel:** + +```hyp +// Aktion 5 mal wiederholen +RepeatAction(5, suggestion() { + observe "Wiederholt!"; +}); + +// Funktionskomposition +suggestion double(x: number): number { + awaken x * 2; +} + +suggestion addTen(x: number): number { + awaken x + 10; +} + +induce composed = Compose(double, addTen); +induce result: number = composed(5); // double(addTen(5)) = 30 +``` + +[→ Detaillierte DeepMind-Funktionen](./deepmind-functions) + +## Verwendung + +Alle Builtin-Funktionen können direkt in HypnoScript-Code verwendet werden, ohne Import: + +```hyp +Focus { + entrance { + observe "=== Builtin-Funktionen Demo ==="; + } + + // Array-Funktionen + induce numbers: number[] = [1, 2, 3, 4, 5]; + induce sum: number = Sum(numbers); + observe "Summe: " + sum; + + // String-Funktionen + induce text: string = "Hallo Welt"; + induce reversed: string = Reverse(text); + observe "Umgekehrt: " + reversed; + + // Mathematische Funktionen + induce sqrt: number = Sqrt(16); + observe "Quadratwurzel von 16: " + sqrt; + + // System-Funktionen + induce os: string = GetOperatingSystem(); + observe "Betriebssystem: " + os; + + // Validierung + induce isValid: boolean = IsValidEmail("test@example.com"); + observe "E-Mail gültig: " + isValid; + + // Statistik + induce mean: number = CalculateMean([1, 2, 3, 4, 5]); + observe "Mittelwert: " + mean; + + finale { + observe "=== Demo beendet ==="; + } +} Relax +``` + +## CLI-Befehl + +Liste alle Builtin-Funktionen im Terminal: + +```bash +hypnoscript builtins +``` + +## Vollständige Referenz + +Für eine vollständige alphabetische Liste aller 110+ Funktionen siehe: + +[→ Vollständige Builtin-Referenz](./_complete-reference) + +## Kategorien-Index + +- [Math-Funktionen](./math-functions) +- [String-Funktionen](./string-functions) +- [Array-Funktionen](./array-functions) +- [Statistik-Funktionen](./statistics-functions) +- [Zeit/Datum-Funktionen](./time-date-functions) +- [System-Funktionen](./system-functions) +- [Datei-Funktionen](./file-functions) +- [Validierung-Funktionen](./validation-functions) +- [Hashing-Funktionen](./hashing-encoding) +- [DeepMind-Funktionen](./deepmind-functions) +- [Hypnotische Funktionen](./hypnotic-functions) + +## Nächste Schritte + +- [Beispiele](../examples/basic-examples) - Praktische Beispiele +- [Language Reference](../language-reference/syntax) - Sprachsyntax +- [CLI Commands](../cli/commands) - Kommandozeilenbefehle diff --git a/HypnoScript.Dokumentation/docs/builtins/performance-functions.md b/hypnoscript-docs/docs/builtins/performance-functions.md similarity index 100% rename from HypnoScript.Dokumentation/docs/builtins/performance-functions.md rename to hypnoscript-docs/docs/builtins/performance-functions.md diff --git a/HypnoScript.Dokumentation/docs/builtins/statistics-functions.md b/hypnoscript-docs/docs/builtins/statistics-functions.md similarity index 100% rename from HypnoScript.Dokumentation/docs/builtins/statistics-functions.md rename to hypnoscript-docs/docs/builtins/statistics-functions.md diff --git a/HypnoScript.Dokumentation/docs/builtins/string-functions.md b/hypnoscript-docs/docs/builtins/string-functions.md similarity index 98% rename from HypnoScript.Dokumentation/docs/builtins/string-functions.md rename to hypnoscript-docs/docs/builtins/string-functions.md index 7ff3436..5801452 100644 --- a/HypnoScript.Dokumentation/docs/builtins/string-functions.md +++ b/hypnoscript-docs/docs/builtins/string-functions.md @@ -4,6 +4,10 @@ sidebar_position: 3 # String-Funktionen +:::tip Vollständige Referenz +Siehe [Builtin-Funktionen Vollständige Referenz](./_complete-reference#string-builtins) für die vollständige, aktuelle Dokumentation aller String-Funktionen. +::: + HypnoScript bietet umfangreiche String-Funktionen für Textverarbeitung, -manipulation und -analyse. ## Grundlegende String-Operationen diff --git a/HypnoScript.Dokumentation/docs/builtins/system-functions.md b/hypnoscript-docs/docs/builtins/system-functions.md similarity index 100% rename from HypnoScript.Dokumentation/docs/builtins/system-functions.md rename to hypnoscript-docs/docs/builtins/system-functions.md diff --git a/HypnoScript.Dokumentation/docs/builtins/time-date-functions.md b/hypnoscript-docs/docs/builtins/time-date-functions.md similarity index 100% rename from HypnoScript.Dokumentation/docs/builtins/time-date-functions.md rename to hypnoscript-docs/docs/builtins/time-date-functions.md diff --git a/HypnoScript.Dokumentation/docs/builtins/utility-functions.md b/hypnoscript-docs/docs/builtins/utility-functions.md similarity index 100% rename from HypnoScript.Dokumentation/docs/builtins/utility-functions.md rename to hypnoscript-docs/docs/builtins/utility-functions.md diff --git a/HypnoScript.Dokumentation/docs/builtins/validation-functions.md b/hypnoscript-docs/docs/builtins/validation-functions.md similarity index 100% rename from HypnoScript.Dokumentation/docs/builtins/validation-functions.md rename to hypnoscript-docs/docs/builtins/validation-functions.md diff --git a/hypnoscript-docs/docs/cli/advanced-commands.md b/hypnoscript-docs/docs/cli/advanced-commands.md new file mode 100644 index 0000000..f3eda29 --- /dev/null +++ b/hypnoscript-docs/docs/cli/advanced-commands.md @@ -0,0 +1,18 @@ +--- +title: Advanced CLI Commands +--- + +Die HypnoScript CLI hält die Zahl der Subcommands bewusst klein. Es gibt aktuell keine versteckten oder „fortgeschrittenen“ Befehle – stattdessen kombinierst du die vorhandenen Tools flexibel. + +## Nützliche Kombinationen + +- **Syntax + Ausführung:** `hypnoscript check file.hyp && hypnoscript run file.hyp --debug` +- **WASM-Pipeline:** `hypnoscript compile-wasm file.hyp && wat2wasm file.wat` +- **AST-Vergleich:** `hypnoscript parse file.hyp > ast.log` + +## Alias-Ideen + +- `alias hrun='hypnoscript run --debug'` +- `function hcheck() { hypnoscript check "$1" && hypnoscript run "$1"; }` + +Weitere Befehle findest du auf der Seite [CLI-Befehle](./commands). diff --git a/hypnoscript-docs/docs/cli/commands.md b/hypnoscript-docs/docs/cli/commands.md new file mode 100644 index 0000000..34fc423 --- /dev/null +++ b/hypnoscript-docs/docs/cli/commands.md @@ -0,0 +1,561 @@ +# CLI-Befehle + +Die HypnoScript CLI (Rust Edition) bietet alle wesentlichen Befehle für Entwicklung, Testing und Analyse von HypnoScript-Programmen. + +## Übersicht + +```bash +hypnoscript [OPTIONS] +``` + +**Verfügbare Befehle:** + +| Befehl | Beschreibung | +| -------------- | ---------------------------------- | +| `run` | Führt ein HypnoScript-Programm aus | +| `lex` | Tokenisiert eine HypnoScript-Datei | +| `parse` | Zeigt den AST einer Datei | +| `check` | Führt Type Checking durch | +| `compile-wasm` | Kompiliert zu WebAssembly (.wat) | +| `version` | Zeigt Versionsinformationen | +| `builtins` | Listet alle Builtin-Funktionen | + +## run - Programm ausführen + +Führt ein HypnoScript-Programm aus. Dies ist der Hauptbefehl für die Ausführung von .hyp-Dateien. + +### Syntax + +```bash +hypnoscript run [OPTIONS] +``` + +### Argumente + +| Argument | Beschreibung | Erforderlich | +| -------- | ------------------- | ------------ | +| `` | Pfad zur .hyp-Datei | ✅ Ja | + +### Optionen + +| Option | Kurzform | Beschreibung | +| ----------- | -------- | ---------------------- | +| `--debug` | `-d` | Debug-Modus aktivieren | +| `--verbose` | `-v` | Ausführliche Ausgabe | + +### Verhalten + +1. **Lexing**: Tokenisiert den Quellcode +2. **Parsing**: Erstellt den AST +3. **Type Checking**: Prüft Typen (Fehler werden als Warnung ausgegeben) +4. **Execution**: Führt das Programm aus + +**Hinweis:** Type-Fehler führen nicht zum Abbruch - das Programm wird trotzdem ausgeführt. + +### Beispiele + +```bash +# Einfache Ausführung +hypnoscript run hello.hyp + +# Mit Debug-Modus +hypnoscript run script.hyp --debug + +# Mit detaillierter Ausgabe +hypnoscript run complex.hyp --verbose + +# Beide Optionen kombiniert +hypnoscript run test.hyp -d -v +``` + +### Debug-Modus Ausgabe + +Im Debug-Modus werden zusätzliche Informationen ausgegeben: + +``` +Running file: script.hyp +Source code: +Focus { ... } + +--- Lexing --- +Tokens: 42 + +--- Type Checking --- + +--- Executing --- + + +✅ Program executed successfully! +``` + +## lex - Tokenisierung + +Tokenisiert eine HypnoScript-Datei und zeigt alle Token an. + +### Syntax + +```bash +hypnoscript lex +``` + +### Argumente + +| Argument | Beschreibung | Erforderlich | +| -------- | ------------------- | ------------ | +| `` | Pfad zur .hyp-Datei | ✅ Ja | + +### Ausgabe + +Listet alle Token mit Index und Typ: + +``` +=== Tokens === + 0: Token { token_type: Focus, lexeme: "Focus", line: 1, column: 1 } + 1: Token { token_type: LBrace, lexeme: "{", line: 1, column: 7 } + 2: Token { token_type: Observe, lexeme: "observe", line: 2, column: 5 } + ... + +Total tokens: 42 +``` + +### Verwendung + +- **Syntax-Debugging**: Verstehen wie der Lexer Code interpretiert +- **Token-Analyse**: Prüfen ob Schlüsselwörter korrekt erkannt werden +- **Lernzwecke**: Verstehen wie HypnoScript-Code tokenisiert wird + +### Beispiel + +```bash +hypnoscript lex examples/01_hello_trance.hyp +``` + +## parse - AST anzeigen + +Parst eine HypnoScript-Datei und zeigt den resultierenden Abstract Syntax Tree (AST). + +### Syntax + +```bash +hypnoscript parse +``` + +### Argumente + +| Argument | Beschreibung | Erforderlich | +| -------- | ------------------- | ------------ | +| `` | Pfad zur .hyp-Datei | ✅ Ja | + +### Ausgabe + +Zeigt den AST in formatierter Form: + +``` +=== AST === +Program([ + FocusBlock([ + ObserveStatement( + StringLiteral("Hallo Welt") + ), + VariableDeclaration { + name: "x", + type_annotation: Some("number"), + initializer: Some(NumberLiteral(42.0)), + is_constant: false + } + ]) +]) +``` + +### Verwendung + +- **Struktur-Analyse**: Verstehen wie Code geparst wird +- **Compiler-Debugging**: Probleme im Parser identifizieren +- **Entwicklung**: AST-Struktur für Compiler-Erweiterungen verstehen + +### Beispiel + +```bash +hypnoscript parse examples/02_variables_arithmetic.hyp +``` + +## check - Type Checking + +Führt Type Checking auf einer HypnoScript-Datei durch und meldet Typ-Fehler. + +### Syntax + +```bash +hypnoscript check +``` + +### Argumente + +| Argument | Beschreibung | Erforderlich | +| -------- | ------------------- | ------------ | +| `` | Pfad zur .hyp-Datei | ✅ Ja | + +### Ausgabe + +**Ohne Fehler:** + +``` +✅ No type errors found! +``` + +**Mit Fehlern:** + +``` +❌ Type errors found: + - Variable 'x' used before declaration at line 5 + - Type mismatch: expected number, got string at line 8 + - Function 'unknown' not defined at line 12 +``` + +### Type Checking Regeln + +Der Type Checker prüft: + +- ✅ Variablendeklarationen +- ✅ Funktionsaufrufe und -signaturen +- ✅ Typ-Kompatibilität in Zuweisungen +- ✅ Array-Typen +- ✅ Session-Member-Zugriffe +- ✅ Return-Statement Typen + +### Verwendung + +- **Vor Deployment**: Typ-Fehler frühzeitig finden +- **Entwicklung**: Code-Qualität sicherstellen +- **CI/CD**: Als Teil der Build-Pipeline + +### Beispiel + +```bash +hypnoscript check src/main.hyp + +# In CI/CD Pipeline +hypnoscript check **/*.hyp +if [ $? -eq 0 ]; then + echo "Type check passed" +else + echo "Type check failed" + exit 1 +fi +``` + +## compile-wasm - WebAssembly Generierung + +Kompiliert ein HypnoScript-Programm zu WebAssembly Text Format (.wat). + +### Syntax + +```bash +hypnoscript compile-wasm [OPTIONS] +``` + +### Argumente + +| Argument | Beschreibung | Erforderlich | +| --------- | -------------------------- | ------------ | +| `` | Pfad zur .hyp-Eingabedatei | ✅ Ja | + +### Optionen + +| Option | Kurzform | Beschreibung | Standard | +| ---------- | -------- | ------------------ | ------------- | +| `--output` | `-o` | Ausgabe-.wat-Datei | `.wat` | + +### Verhalten + +1. **Parsing**: Erstellt AST aus Quellcode +2. **Code Generation**: Generiert WASM-Text-Format +3. **Ausgabe**: Schreibt .wat-Datei + +**Hinweis:** Die generierte .wat-Datei kann mit Tools wie `wat2wasm` zu binärem WASM kompiliert werden. + +### Ausgabe + +``` +✅ WASM code written to: output.wat +``` + +### Beispiele + +```bash +# Standard-Ausgabe (script.wat) +hypnoscript compile-wasm script.hyp + +# Custom Ausgabedatei +hypnoscript compile-wasm script.hyp --output program.wat +hypnoscript compile-wasm script.hyp -o program.wat + +# Komplett zu binärem WASM (benötigt wabt) +hypnoscript compile-wasm script.hyp +wat2wasm script.wat -o script.wasm +``` + +### WASM-Integration + +Nach Kompilierung kann das WASM-Modul in verschiedenen Umgebungen verwendet werden: + +**Web (JavaScript):** + +```javascript +WebAssembly.instantiateStreaming(fetch('script.wasm')).then((module) => { + // Nutze exportierte Funktionen +}); +``` + +**Node.js:** + +```javascript +const fs = require('fs'); +const bytes = fs.readFileSync('script.wasm'); +const module = await WebAssembly.instantiate(bytes); +``` + +## version - Versionsinformationen + +Zeigt Versionsinformationen und Features der HypnoScript CLI. + +### Syntax + +```bash +hypnoscript version +``` + +### Ausgabe + +``` +HypnoScript v1.0.0 (Rust Edition) +The Hypnotic Programming Language + +Migrated from C# to Rust for improved performance + +Features: + - Full parser and interpreter + - Type checker + - WASM code generation + - 110+ builtin functions +``` + +### Verwendung + +- **Version prüfen**: Aktuell installierte Version feststellen +- **Feature-Überblick**: Verfügbare Funktionalität anzeigen +- **Debugging**: Version in Bug-Reports angeben + +### Beispiel + +```bash +hypnoscript version +``` + +## builtins - Builtin-Funktionen auflisten + +Listet alle verfügbaren Builtin-Funktionen der HypnoScript Standard-Bibliothek. + +### Syntax + +```bash +hypnoscript builtins +``` + +### Ausgabe + +``` +=== HypnoScript Builtin Functions === + +📊 Math Builtins: + - Sin, Cos, Tan, Sqrt, Pow, Log, Log10 + - Abs, Floor, Ceil, Round, Min, Max + - Factorial, Gcd, Lcm, IsPrime, Fibonacci + - Clamp + +📝 String Builtins: + - Length, ToUpper, ToLower, Trim + - IndexOf, Replace, Reverse, Capitalize + - StartsWith, EndsWith, Contains + - Split, Substring, Repeat + - PadLeft, PadRight + +📦 Array Builtins: + - Length, IsEmpty, Get, IndexOf, Contains + - Reverse, Sum, Average, Min, Max, Sort + - First, Last, Take, Skip, Slice + - Join, Count, Distinct + +✨ Hypnotic Builtins: + - observe (output) + - drift (sleep) + - DeepTrance + - HypnoticCountdown + - TranceInduction + - HypnoticVisualization + +🔄 Conversion Functions: + - ToInt, ToDouble, ToString, ToBoolean + +Total: 50+ builtin functions implemented +``` + +### Verwendung + +- **Referenz**: Schnell nachschlagen welche Funktionen verfügbar sind +- **Entwicklung**: Entdecken neuer Funktionalität +- **Dokumentation**: Liste für eigene Referenzen + +### Beispiel + +```bash +# Auflisten +hypnoscript builtins + +# Ausgabe in Datei umleiten +hypnoscript builtins > builtin-reference.txt + +# Filtern mit grep +hypnoscript builtins | grep "Array" +``` + +## Globale Optionen + +Diese Optionen funktionieren mit allen Befehlen: + +| Option | Kurzform | Beschreibung | +| ----------- | -------- | -------------------- | +| `--help` | `-h` | Zeigt Hilfe | +| `--version` | `-V` | Zeigt Version (kurz) | + +### Beispiele + +```bash +# Hilfe für Hauptbefehl +hypnoscript --help + +# Hilfe für Unterbefehl +hypnoscript run --help + +# Kurzversion +hypnoscript --version +``` + +## Exit Codes + +Die CLI verwendet Standard-Exit-Codes: + +| Code | Bedeutung | +| ---- | --------------------------- | +| `0` | Erfolg | +| `1` | Fehler (Parse/Type/Runtime) | + +### Verwendung in Scripts + +```bash +#!/bin/bash + +hypnoscript check script.hyp +if [ $? -eq 0 ]; then + hypnoscript run script.hyp +else + echo "Type check failed!" + exit 1 +fi +``` + +## Best Practices + +### Entwicklungs-Workflow + +1. **Schreiben**: Code in .hyp-Datei schreiben +2. **Prüfen**: `hypnoscript check script.hyp` +3. **Testen**: `hypnoscript run script.hyp --debug` +4. **Optimieren**: Bei Bedarf Code anpassen +5. **Deployen**: Final mit `hypnoscript run script.hyp` + +### Debugging-Workflow + +1. **Lexing prüfen**: `hypnoscript lex script.hyp` +2. **AST prüfen**: `hypnoscript parse script.hyp` +3. **Typen prüfen**: `hypnoscript check script.hyp` +4. **Ausführen**: `hypnoscript run script.hyp --debug --verbose` + +### CI/CD Integration + +```yaml +# GitHub Actions Beispiel +steps: + - name: Install HypnoScript + run: cargo install --path hypnoscript-cli + + - name: Type Check + run: hypnoscript check src/**/*.hyp + + - name: Run Tests + run: | + for file in tests/*.hyp; do + hypnoscript run "$file" + done + + - name: Build WASM + run: hypnoscript compile-wasm src/main.hyp -o dist/app.wat +``` + +## Tipps & Tricks + +### Shell-Aliase + +Vereinfache häufige Befehle: + +```bash +# In ~/.bashrc oder ~/.zshrc +alias hyp='hypnoscript' +alias hyp-run='hypnoscript run' +alias hyp-check='hypnoscript check' +alias hyp-wasm='hypnoscript compile-wasm' +``` + +Verwendung: + +```bash +hyp run script.hyp +hyp-check script.hyp +hyp-wasm script.hyp +``` + +### Batch-Verarbeitung + +```bash +# Alle .hyp-Dateien prüfen +for file in **/*.hyp; do + echo "Checking $file..." + hypnoscript check "$file" +done + +# Alle Tests ausführen +for file in tests/*.hyp; do + echo "Running $file..." + hypnoscript run "$file" +done +``` + +### Output Redirection + +```bash +# Fehler in Datei schreiben +hypnoscript run script.hyp 2> errors.log + +# Ausgabe UND Fehler +hypnoscript run script.hyp &> complete.log + +# Nur Fehler anzeigen +hypnoscript run script.hyp 2>&1 >/dev/null +``` + +## Siehe auch + +- [Quick Start](../getting-started/quick-start) - Erste Schritte +- [Debugging](./debugging) - Erweiterte Debugging-Techniken +- [Configuration](./configuration) - CLI-Konfiguration +- [Builtin Functions](../builtins/overview) - Referenz aller Funktionen diff --git a/hypnoscript-docs/docs/cli/configuration.md b/hypnoscript-docs/docs/cli/configuration.md new file mode 100644 index 0000000..6e25220 --- /dev/null +++ b/hypnoscript-docs/docs/cli/configuration.md @@ -0,0 +1,138 @@ +--- +sidebar_position: 3 +--- + +# CLI-Konfiguration + +Die Rust-basierte HypnoScript CLI verzichtet bewusst auf globale Konfigurationsdateien. Stattdessen steuerst du das Verhalten ausschließlich über Subcommands und deren Flags. Dieser Leitfaden zeigt, welche Schalter es gibt und wie du sie mit Shell-Skripten oder Tooling automatisieren kannst. + +## Laufzeit-Flags der CLI + +| Subcommand | Optionen | Wirkung | +| ----------------------------------- | ---------------------- | ------------------------------------------------------------------------- | +| `run ` | `--debug`, `--verbose` | Debug zeigt Tokens, AST und Type Checks, verbose gibt Statusmeldungen aus | +| `compile-wasm` | `--output ` | Wählt den Namen der `.wat`-Datei (Standard: `.wat`) | +| `version` | _(keine)_ | Gibt Toolchain-Informationen aus | +| `lex`, `parse`, `check`, `builtins` | _(keine)_ | Nutzen keine Zusatzoptionen | + +Mehr Flags existieren aktuell nicht. Das macht die CLI zwar simpel, aber auch sehr vorhersehbar – gerade für Skripte und CI. + +## Eigene Wrapper erstellen + +Wenn du häufig dieselben Optionen verwenden möchtest, lohnt sich ein kleines Wrapper-Skript. + +### PowerShell (Windows) + +```powershell +function Invoke-HypnoScriptRun { + param( + [Parameter(Mandatory=$true)] + [string]$File, + [switch]$Debug, + [switch]$Verbose + ) + + $args = @('run', $File) + if ($Debug) { $args += '--debug' } + if ($Verbose) { $args += '--verbose' } + hypnoscript @args +} + +# Nutzung +Invoke-HypnoScriptRun -File 'scripts/demo.hyp' -Verbose +``` + +### Bash / Zsh (macOS, Linux) + +```bash +hyp() { + local mode="$1"; shift + case "$mode" in + run) + hypnoscript run "$@" --verbose ;; + check) + hypnoscript check "$@" ;; + *) + hypnoscript "$mode" "$@" ;; + esac +} + +# Beispiel +hyp run scripts/demo.hyp +``` + +Solche Wrapper kannst du versionskontrolliert im Projekt ablegen (`scripts/`). + +## Projektbezogene Workflows + +Auch ohne Konfigurationsdatei kannst du Abläufe bündeln: + +- **`package.json` / npm scripts:** `"check": "hypnoscript check src/**/*.hyp"` +- **Makefile:** `check: ; hypnoscript check $(FILE)` +- **CI-Pipeline:** Verwende die `run`, `check` und `compile-wasm` Befehle direkt in deinen Jobs. + +Damit dokumentierst du, wie das Projekt gebaut oder geprüft werden soll – ohne eigene CLI-Config. + +## Umgebungsvariablen + +Die CLI liest derzeit keine speziellen `HYPNOSCRIPT_*` Variablen ein. Du kannst trotzdem Umgebungsvariablen nutzen, um Dateipfade oder Flags zu steuern: + +```bash +export HYPNO_DEFAULT=examples/intro.hyp +hypnoscript run "$HYPNO_DEFAULT" +``` + +Oder in PowerShell: + +```powershell +$env:DEFAULT_HYP = 'examples/intro.hyp' +hypnoscript run $env:DEFAULT_HYP --debug +``` + +Solche Variablen sind rein konventionell – die CLI greift nicht automatisch darauf zu. + +## Empfehlungen + +- **Dokumentiere Wrapper:** Lege ein README im `scripts/`-Ordner an, damit andere den Workflow nachvollziehen können. +- **Nutze `--debug` sparsam:** In CI-Pipelines reicht oft `--verbose`. Debug-Ausgaben können riesig werden. +- **Version pinnen:** Referenziere in Skripten eine konkrete Version (`hypnoscript version`) oder lege den Binary als Artefakt ab, um reproduzierbare Builds zu erhalten. + +## Troubleshooting + +1. **`hypnoscript` wird nicht gefunden** + +```bash +# Prüfe, ob der Binary im PATH liegt +which hypnoscript # macOS/Linux +Get-Command hypnoscript | Select-Object Source # PowerShell + +# Falls nicht vorhanden: Pfad ergänzen +export PATH="$PATH:$HOME/.cargo/bin" # Beispiel Linux +``` + +1. **Keine Ausführungsrechte** + +```bash +chmod +x hypnoscript # macOS/Linux +Set-ExecutionPolicy RemoteSigned # Windows PowerShell (falls nötig) +``` + +1. **Unerwartete Ausgaben / Syntaxfehler** + +```bash +# Mit Debug-Infos erneut ausführen +hypnoscript run script.hyp --debug + +# Tokens prüfen +hypnoscript lex script.hyp +``` + +## Nächste Schritte + +- [CLI Übersicht](./overview) – Installationswege & Workflow +- [CLI-Befehle](./commands) – Vollständige Referenz der Subcommands +- [CLI Basics](../getting-started/cli-basics) – Alltagstaugliche Beispiele + +--- + +**Tipp:** Baue eigene Wrapper in `scripts/`, um wiederkehrende Aufrufe zu vereinfachen. diff --git a/hypnoscript-docs/docs/cli/debugging.md b/hypnoscript-docs/docs/cli/debugging.md new file mode 100644 index 0000000..361ddad --- /dev/null +++ b/hypnoscript-docs/docs/cli/debugging.md @@ -0,0 +1,50 @@ +--- +title: CLI Debugging +--- + +Die HypnoScript CLI setzt beim Debugging auf wenige, aber wirkungsvolle Mechanismen. Dieser Leitfaden zeigt, wie du Fehler schnell eingrenzt und welche Befehle dir helfen, den Programmzustand sichtbar zu machen. + +## Debug- und Verbose-Modus + +- `--debug` zeigt den Quelltext, die erzeugten Tokens, den AST sowie die Ergebnisse des Type Checkers, bevor der Interpreter startet. +- `--verbose` ergänzt Statusmeldungen (z.B. "Running file" oder "Program executed successfully"). +- Beide Flags lassen sich kombinieren: `hypnoscript run script.hyp --debug --verbose`. + +## Token- und AST-Analyse + +```bash +hypnoscript lex script.hyp +hypnoscript parse script.hyp +``` + +- Nutze `lex`, um zu kontrollieren, welche Schlüsselwörter und Literale der Lexer erkennt. +- `parse` liefert den vollständigen AST – ideal, wenn Kontrollstrukturen oder Sessions nicht wie erwartet aufgebaut werden. + +## Typprüfung ohne Ausführung + +```bash +hypnoscript check script.hyp +``` + +- Der Type Checker meldet fehlende Funktionen, falsche Rückgabewerte oder ungeeignete Zuweisungen. +- Die CLI führt das Programm auch bei Typfehlern aus; verwende `check`, um Fehler schon vorher einzufangen. + +## Typischer Debug-Workflow + +```bash +# 1. Type Checking +hypnoscript check scripts/deep_trance.hyp + +# 2. Tokens & AST inspizieren +hypnoscript lex scripts/deep_trance.hyp +hypnoscript parse scripts/deep_trance.hyp + +# 3. Mit Debug-Ausgabe ausführen +hypnoscript run scripts/deep_trance.hyp --debug +``` + +## Tipps + +- Kommentiere komplexe Bereiche temporär aus (`//`) und führe den Rest mit `--debug` aus, um das Problem lokal einzugrenzen. +- Bei Array-Operationen hilft `hypnoscript builtins`, um passende Hilfsfunktionen zu finden (z.B. `ArrayJoin`, `ArrayContains`). +- Speichere Debug-Ausgaben mit `> debug.log`, falls du sie später vergleichen möchtest (`hypnoscript run script.hyp --debug > debug.log`). diff --git a/HypnoScript.Dokumentation/docs/cli/enterprise-features.md b/hypnoscript-docs/docs/cli/enterprise-features.md similarity index 100% rename from HypnoScript.Dokumentation/docs/cli/enterprise-features.md rename to hypnoscript-docs/docs/cli/enterprise-features.md diff --git a/hypnoscript-docs/docs/cli/overview.md b/hypnoscript-docs/docs/cli/overview.md new file mode 100644 index 0000000..62d0aa0 --- /dev/null +++ b/hypnoscript-docs/docs/cli/overview.md @@ -0,0 +1,89 @@ +--- +sidebar_position: 1 +--- + +# CLI Übersicht + +Die HypnoScript Command Line Interface (CLI) ist ein in Rust gebautes Einzelbinary (`hypnoscript`). Es bündelt Lexer, Parser, Type Checker, Interpreter und den WASM-Codegenerator in einem Tool. + +## Installation + +### Vorgefertigte Pakete + +1. Lade das passende Archiv aus den [GitHub Releases](https://github.com/Kink-Development-Group/hyp-runtime/releases). +2. Entpacke das Archiv und füge den Binärpfad deiner `PATH`-Umgebungsvariable hinzu. +3. Prüfe die Installation mit `hypnoscript version`. + +### Aus dem Quellcode bauen + +```bash +git clone https://github.com/Kink-Development-Group/hyp-runtime.git +cd hyp-runtime +cargo build --release -p hypnoscript-cli +# Optional installieren +cargo install --path hypnoscript-cli +``` + +Die kompilierten Binaries findest du unter `target/release/`. + +## Schnellstart + +```bash +# Hilfe anzeigen +hypnoscript --help + +# Versionshinweis +hypnoscript version + +# Programm ausführen +hypnoscript run hello.hyp +``` + +Alle Subcommands sind bewusst schlank gehalten. Für einen tieferen Blick sieh dir die folgenden Abschnitte an. + +## Befehlsüberblick + +| Befehl | Kurzbeschreibung | +| -------------- | ------------------------------------------- | +| `run` | Führt ein HypnoScript-Programm aus | +| `run --debug` | Zeigt zusätzlich Tokens, AST und Typprüfung | +| `lex` | Tokenisiert eine Datei | +| `parse` | Zeigt den AST | +| `check` | Führt Type Checking durch | +| `compile-wasm` | Generiert WebAssembly Text Format (.wat) | +| `builtins` | Listet alle verfügbaren Builtin-Funktionen | +| `version` | Zeigt Versions- und Featureinformationen | + +Weitere Details liefert die Seite [CLI-Befehle](./commands). + +## Typischer Workflow + +```bash +# 1. Type Checking ohne Ausführung +hypnoscript check my_script.hyp + +# 2. Bei Fehlern AST prüfen +hypnoscript parse my_script.hyp + +# 3. Debug-Ausgabe aktivieren +hypnoscript run my_script.hyp --debug + +# 4. Optional WASM generieren +hypnoscript compile-wasm my_script.hyp -o my_script.wat +``` + +## Plattformhinweise + +- **Windows**: Nutze das ZIP aus dem Release, entpacke in `%LOCALAPPDATA%\Programs\hypnoscript` und ergänze den Pfad. +- **macOS / Linux**: Archiv nach `/usr/local/bin` oder `~/.local/bin` kopieren. +- Für portable Nutzung kannst du den Binary-Pfad direkt angeben (`./hypnoscript run demo.hyp`). + +## Nächste Schritte + +- [CLI-Befehle](./commands) – Details zu allen Subcommands +- [CLI Basics](../getting-started/cli-basics) – Schritt-für-Schritt-Anleitung +- [Sprachreferenz](../language-reference/syntax) – Grammatik & Beispiele + +--- + +**Tipp:** `hypnoscript builtins` verschafft dir einen schnellen Überblick über die Standardbibliothek. diff --git a/hypnoscript-docs/docs/cli/testing.md b/hypnoscript-docs/docs/cli/testing.md new file mode 100644 index 0000000..33fb82f --- /dev/null +++ b/hypnoscript-docs/docs/cli/testing.md @@ -0,0 +1,54 @@ +--- +title: CLI Testing +--- + +Die Rust-CLI enthält kein separates Test-Framework. Stattdessen behandelst du jede `.hyp`-Datei als eigenständiges Skript und führst sie mit `hypnoscript run` aus. Die Dateien im Ordner `hypnoscript-tests/` liefern Beispiele für Assertions und Fehlermeldungen. + +## Tests ausführen + +```bash +# Einzelne Testdatei starten +hypnoscript run hypnoscript-tests/test_basic.hyp + +# Alle Dateien im Ordner durchlaufen +for file in hypnoscript-tests/*.hyp; do + echo "== $file ==" + hypnoscript run "$file" +done +``` + +## Typprüfung vorgeschaltet + +```bash +hypnoscript check hypnoscript-tests/test_basic.hyp +``` + +So erkennst du Typfehler, bevor Assertions greifen. Die CLI bricht bei Fehlern nicht automatisch ab, daher lohnt sich ein separates `check` vor dem `run`. + +## Integration in Skripte + +- **PowerShell:** + + ```powershell + Get-ChildItem hypnoscript-tests -Filter *.hyp | ForEach-Object { + Write-Host "== $($_.Name) ==" + hypnoscript run $_.FullName + } + ``` + +- **Makefile:** + + ```makefile + test: + @# Ersetze führende Leerzeichen durch Tabs, da Make dies erfordert + @for file in hypnoscript-tests/*.hyp; do \ + echo "== $$file =="; \ + hypnoscript run $$file || exit 1; \ + done + ``` + +## Assertions + +Die Test-Dateien nutzen `assert`-Statements sowie `observe`, um erwartete Werte zu prüfen. Bricht ein Assertion-Block ab, zeigt die CLI eine Fehlermeldung an, setzt die Ausführung aber fort. Achte deshalb darauf, im Testskript nach Fehlermeldungen zu suchen oder das Skript bei Bedarf mit `snap;` zu beenden. + +Mehr über verfügbare Befehle erfährst du in [CLI-Befehle](./commands). diff --git a/HypnoScript.Dokumentation/docs/debugging/best-practices.md b/hypnoscript-docs/docs/debugging/best-practices.md similarity index 100% rename from HypnoScript.Dokumentation/docs/debugging/best-practices.md rename to hypnoscript-docs/docs/debugging/best-practices.md diff --git a/hypnoscript-docs/docs/debugging/breakpoints.md b/hypnoscript-docs/docs/debugging/breakpoints.md new file mode 100644 index 0000000..6003434 --- /dev/null +++ b/hypnoscript-docs/docs/debugging/breakpoints.md @@ -0,0 +1,23 @@ +# Breakpoints + +Breakpoints let you pause a HypnoScript session at precise trance steps to inspect memory and hypnotic state transitions. + +## Setting Breakpoints + +- In the CLI, use `hypnoscript debug script.hyp --break label_name` to stop before the instruction tagged with `label_name`. +- Inside editors that support the HypnoScript language server, click the gutter to toggle a breakpoint; the location is saved in `.hypdbg` files. + +## Inspecting State + +While paused, you can: + +- Run `state show` to dump the trance stack and current suggestion payload. +- Evaluate expressions with `eval ` to probe variable values without resuming the script. + +## Stepping Controls + +Use the following commands to progress through the script: + +- `step` advances a single instruction, entering nested suggestions. +- `next` executes the current instruction and pauses at the following one, skipping over nested sequences. +- `continue` resumes execution until the next breakpoint or the end of the session. diff --git a/hypnoscript-docs/docs/debugging/debug-mode.md b/hypnoscript-docs/docs/debugging/debug-mode.md new file mode 100644 index 0000000..e90b719 --- /dev/null +++ b/hypnoscript-docs/docs/debugging/debug-mode.md @@ -0,0 +1,23 @@ +# Debug Mode + +Debug mode provides fine-grained insight into HypnoScript execution, exposing the virtual machine state, trance stack, and hypnotic suggestions as they execute. + +## Enabling Debug Mode + +Run any script with the `--debug` flag: `hypnoscript --debug session.hyp`. The CLI generates a structured log under `target/debug-logs/` with a timestamped filename. + +## Output Format + +The debug log is newline-delimited JSON. Each entry includes: + +- `phase`: parser, compiler, or runtime +- `instruction`: mnemonic of the instruction currently executing +- `context`: key variables and induction parameters at that step + +## Integrating With Editors + +The HypnoScript VS Code extension reads the debug log and overlays inline diagnostics. Open the “Hypnotic Timeline” panel to replay the execution while watching stack depth and suggestion intensity changes. + +## Performance Considerations + +Debug mode slows execution because every instruction emits detailed telemetry. Avoid using it during latency-sensitive live inductions; capture traces in staging first, review them, and then rerun in release mode. diff --git a/HypnoScript.Dokumentation/docs/debugging/overview.md b/hypnoscript-docs/docs/debugging/overview.md similarity index 100% rename from HypnoScript.Dokumentation/docs/debugging/overview.md rename to hypnoscript-docs/docs/debugging/overview.md diff --git a/HypnoScript.Dokumentation/docs/debugging/performance.md b/hypnoscript-docs/docs/debugging/performance.md similarity index 100% rename from HypnoScript.Dokumentation/docs/debugging/performance.md rename to hypnoscript-docs/docs/debugging/performance.md diff --git a/HypnoScript.Dokumentation/docs/debugging/tools.md b/hypnoscript-docs/docs/debugging/tools.md similarity index 100% rename from HypnoScript.Dokumentation/docs/debugging/tools.md rename to hypnoscript-docs/docs/debugging/tools.md diff --git a/hypnoscript-docs/docs/debugging/troubleshooting.md b/hypnoscript-docs/docs/debugging/troubleshooting.md new file mode 100644 index 0000000..f10a8ec --- /dev/null +++ b/hypnoscript-docs/docs/debugging/troubleshooting.md @@ -0,0 +1,20 @@ +# Troubleshooting + +When a HypnoScript session misbehaves, work through the following checklist before diving into the runtime internals. + +## Confirm the Execution Environment + +- Verify the CLI version with `hypnoscript --version` and ensure it matches the runtime bundled with your project. +- Inspect `hypnoscript.toml` for stale paths—especially the `session_dir` and custom induction libraries. + +## Inspect Runtime Logs + +Enable verbose logging with `--trace` to capture stack transitions and variable bindings. Store the resulting log alongside the failing script so regressions can be compared. + +## Reduce the Scenario + +Comment out non-essential trance steps until the failure disappears. This narrows down the instruction or builtin that triggers the issue and keeps the reproduction file short. + +## Validate External Integrations + +Check network credentials, file permissions, and long-running hypnotic hooks whenever a script depends on external systems. Most “hangs” originate from constrained resources rather than the interpreter itself. diff --git a/HypnoScript.Dokumentation/docs/development/debugging.md b/hypnoscript-docs/docs/development/debugging.md similarity index 100% rename from HypnoScript.Dokumentation/docs/development/debugging.md rename to hypnoscript-docs/docs/development/debugging.md diff --git a/HypnoScript.Dokumentation/docs/enterprise/api-management.md b/hypnoscript-docs/docs/enterprise/api-management.md similarity index 100% rename from HypnoScript.Dokumentation/docs/enterprise/api-management.md rename to hypnoscript-docs/docs/enterprise/api-management.md diff --git a/HypnoScript.Dokumentation/docs/enterprise/architecture.md b/hypnoscript-docs/docs/enterprise/architecture.md similarity index 100% rename from HypnoScript.Dokumentation/docs/enterprise/architecture.md rename to hypnoscript-docs/docs/enterprise/architecture.md diff --git a/HypnoScript.Dokumentation/docs/enterprise/backup-recovery.md b/hypnoscript-docs/docs/enterprise/backup-recovery.md similarity index 100% rename from HypnoScript.Dokumentation/docs/enterprise/backup-recovery.md rename to hypnoscript-docs/docs/enterprise/backup-recovery.md diff --git a/HypnoScript.Dokumentation/docs/enterprise/database.md b/hypnoscript-docs/docs/enterprise/database.md similarity index 100% rename from HypnoScript.Dokumentation/docs/enterprise/database.md rename to hypnoscript-docs/docs/enterprise/database.md diff --git a/HypnoScript.Dokumentation/docs/enterprise/debugging.md b/hypnoscript-docs/docs/enterprise/debugging.md similarity index 100% rename from HypnoScript.Dokumentation/docs/enterprise/debugging.md rename to hypnoscript-docs/docs/enterprise/debugging.md diff --git a/HypnoScript.Dokumentation/docs/enterprise/features.md b/hypnoscript-docs/docs/enterprise/features.md similarity index 100% rename from HypnoScript.Dokumentation/docs/enterprise/features.md rename to hypnoscript-docs/docs/enterprise/features.md diff --git a/HypnoScript.Dokumentation/docs/enterprise/integration.md b/hypnoscript-docs/docs/enterprise/integration.md similarity index 100% rename from HypnoScript.Dokumentation/docs/enterprise/integration.md rename to hypnoscript-docs/docs/enterprise/integration.md diff --git a/HypnoScript.Dokumentation/docs/enterprise/messaging.md b/hypnoscript-docs/docs/enterprise/messaging.md similarity index 100% rename from HypnoScript.Dokumentation/docs/enterprise/messaging.md rename to hypnoscript-docs/docs/enterprise/messaging.md diff --git a/HypnoScript.Dokumentation/docs/enterprise/monitoring.md b/hypnoscript-docs/docs/enterprise/monitoring.md similarity index 100% rename from HypnoScript.Dokumentation/docs/enterprise/monitoring.md rename to hypnoscript-docs/docs/enterprise/monitoring.md diff --git a/HypnoScript.Dokumentation/docs/enterprise/overview.md b/hypnoscript-docs/docs/enterprise/overview.md similarity index 100% rename from HypnoScript.Dokumentation/docs/enterprise/overview.md rename to hypnoscript-docs/docs/enterprise/overview.md diff --git a/HypnoScript.Dokumentation/docs/enterprise/security.md b/hypnoscript-docs/docs/enterprise/security.md similarity index 100% rename from HypnoScript.Dokumentation/docs/enterprise/security.md rename to hypnoscript-docs/docs/enterprise/security.md diff --git a/hypnoscript-docs/docs/error-handling/basics.md b/hypnoscript-docs/docs/error-handling/basics.md new file mode 100644 index 0000000..cb2adfd --- /dev/null +++ b/hypnoscript-docs/docs/error-handling/basics.md @@ -0,0 +1,32 @@ +# Error Handling Basics + +HypnoScript surfaces recoverable issues as `WARN` events and fatal problems as `ERROR` events. Understanding the distinction keeps trance sessions safe and predictable. + +## Categorizing Issues + +- **Warnings** signal soft failures—missing optional cues, transient network hiccups, or deprecated suggestions. The session continues unless you explicitly abort. +- **Errors** terminate execution. They commonly arise from type mismatches, invalid hypnotic targets, or uncaught runtime panics in custom extensions. + +## Handling Warnings + +Use the `ON WARN` block to intercept warnings and supply fallback logic: + +```hypnoscript +ON WARN (event) { + LOG "Switching to calm fallback"; + SUGGEST calm_state(); +} +``` + +## Handling Errors + +Wrap dangerous instructions with `TRY`/`CATCH` to restore the participant to a safe default state before propagating the failure: + +```hypnoscript +TRY { + SUGGEST deep_trance(); +} CATCH (err) { + LOG err.message; + SUGGEST safe_exit(); +} +``` diff --git a/hypnoscript-docs/docs/error-handling/common-errors.md b/hypnoscript-docs/docs/error-handling/common-errors.md new file mode 100644 index 0000000..a50a384 --- /dev/null +++ b/hypnoscript-docs/docs/error-handling/common-errors.md @@ -0,0 +1,14 @@ +# Common Errors + +The table below lists frequently reported error codes and the usual steps to resolve them. + +| Code | Meaning | Typical Fix | +| ------ | -------------------------------------- | -------------------------------------------------------------------------------------------- | +| HS1001 | Unknown suggestion or induction | Check the spelling or ensure the module exposing the suggestion is imported. | +| HS2004 | Type mismatch while binding a variable | Coerce the value with `CAST` or adjust the variable declaration to match the inferred type. | +| HS3010 | Session timeout reached | Increase the timeout in `hypnoscript.toml` or optimize long-running routines. | +| HS4002 | Unsafe file access blocked | Add the directory to the allowed paths list or run with elevated permissions if appropriate. | + +## Next Steps + +If an error is missing from this table, enable debug mode, capture the full trace, and file an issue with the log attached so the runtime team can expand the catalog. diff --git a/HypnoScript.Dokumentation/docs/error-handling/overview.md b/hypnoscript-docs/docs/error-handling/overview.md similarity index 100% rename from HypnoScript.Dokumentation/docs/error-handling/overview.md rename to hypnoscript-docs/docs/error-handling/overview.md diff --git a/HypnoScript.Dokumentation/docs/examples/array-examples.md b/hypnoscript-docs/docs/examples/array-examples.md similarity index 100% rename from HypnoScript.Dokumentation/docs/examples/array-examples.md rename to hypnoscript-docs/docs/examples/array-examples.md diff --git a/hypnoscript-docs/docs/examples/basic-examples.md b/hypnoscript-docs/docs/examples/basic-examples.md new file mode 100644 index 0000000..ffff358 --- /dev/null +++ b/hypnoscript-docs/docs/examples/basic-examples.md @@ -0,0 +1,77 @@ +--- +title: Basic Examples +--- + +This page demonstrates common session scenarios that highlight the latest language and type-checker capabilities around constructors, static members, and visibility. + +## Session constructors + +Constructors let you hydrate a session with the right defaults. They run automatically immediately after `SessionName(...)` is called. + +```hypnoscript +Focus { + session Account { + conceal balance: number = 0; + + expose suggestion constructor(initialBalance: number) { + this.balance = initialBalance; + } + + expose suggestion deposit(amount: number) { + this.balance = this.balance + amount; + } + + expose suggestion current(): number { + awaken this.balance; + } + } + + induce savings = Account(250); + savings.deposit(50); + induce balanceNow: number = savings.current(); +} Relax +``` + +The type checker verifies that the constructor receives exactly one numeric argument and that `current()` returns a number. + +## Static configuration + +Static members (prefixed with `dominant`) belong to the session type instead of an instance. They are ideal for global configuration knobs. + +```hypnoscript +Focus { + session Config { + dominant expose environment: string = "dev"; + + dominant suggestion switch(target: string) { + Config.environment = target; + } + } + + Config.switch("prod"); + induce activeEnv: string = Config.environment; +} Relax +``` + +When you attempt to rewrite `Config.environment` through an instance (for example `config.environment = ...`) the type checker refuses the script with: `Assign static field 'environment' through session 'Config', not an instance`. + +## Visibility enforcement + +Encapsulate sensitive state with `conceal`. The compiler catches accidental leaks before runtime. + +```hypnoscript +Focus { + session Vault { + conceal pin: number = 1337; + expose suggestion reveal(): number { + awaken this.pin; + } + } + + induce safe = Vault(); + induce pin = safe.reveal(); + induce leaked = safe.pin; // Field 'pin' of session 'Vault' is not visible here +} Relax +``` + +Only the `reveal()` method can read the concealed field. Every other attempt triggers a type checker diagnostic identical to the inline comment above. diff --git a/HypnoScript.Dokumentation/docs/examples/cli-workflows.md b/hypnoscript-docs/docs/examples/cli-workflows.md similarity index 100% rename from HypnoScript.Dokumentation/docs/examples/cli-workflows.md rename to hypnoscript-docs/docs/examples/cli-workflows.md diff --git a/HypnoScript.Dokumentation/docs/examples/math-examples.md b/hypnoscript-docs/docs/examples/math-examples.md similarity index 100% rename from HypnoScript.Dokumentation/docs/examples/math-examples.md rename to hypnoscript-docs/docs/examples/math-examples.md diff --git a/HypnoScript.Dokumentation/docs/examples/string-examples.md b/hypnoscript-docs/docs/examples/string-examples.md similarity index 100% rename from HypnoScript.Dokumentation/docs/examples/string-examples.md rename to hypnoscript-docs/docs/examples/string-examples.md diff --git a/HypnoScript.Dokumentation/docs/examples/system-examples.md b/hypnoscript-docs/docs/examples/system-examples.md similarity index 100% rename from HypnoScript.Dokumentation/docs/examples/system-examples.md rename to hypnoscript-docs/docs/examples/system-examples.md diff --git a/HypnoScript.Dokumentation/docs/examples/therapeutic-examples.md b/hypnoscript-docs/docs/examples/therapeutic-examples.md similarity index 100% rename from HypnoScript.Dokumentation/docs/examples/therapeutic-examples.md rename to hypnoscript-docs/docs/examples/therapeutic-examples.md diff --git a/HypnoScript.Dokumentation/docs/examples/utility-examples.md b/hypnoscript-docs/docs/examples/utility-examples.md similarity index 100% rename from HypnoScript.Dokumentation/docs/examples/utility-examples.md rename to hypnoscript-docs/docs/examples/utility-examples.md diff --git a/hypnoscript-docs/docs/getting-started/cli-basics.md b/hypnoscript-docs/docs/getting-started/cli-basics.md new file mode 100644 index 0000000..510a9a9 --- /dev/null +++ b/hypnoscript-docs/docs/getting-started/cli-basics.md @@ -0,0 +1,89 @@ +--- +title: CLI Basics +--- + +Die HypnoScript Command Line Interface (CLI) ist das schnellste Werkzeug, um HypnoScript-Skripte zu bauen, zu prüfen und auszuführen. Diese Seite führt dich durch die wichtigsten Subcommands und typischen Arbeitsabläufe. + +## Hilfe & Orientierung + +```bash +# Globale Hilfe +hypnoscript --help + +# Version und Features anzeigen +hypnoscript version + +# Hilfe für einen Subcommand +hypnoscript run --help +``` + +Die Ausgabe listet immer alle verfügbaren Subcommands sowie deren Optionen auf. Falls ein Befehl unbekannt wirkt, lohnt sich ein Blick in `--help` – der Text wird direkt aus der tatsächlichen CLI generiert. + +## Skripte ausführen + +```bash +# Standardausführung +hypnoscript run demo.hyp + +# Mit zusätzlicher Ausgabe +hypnoscript run demo.hyp --verbose + +# Mit Debug-Informationen +hypnoscript run demo.hyp --debug +``` + +- `--verbose` gibt Statusmeldungen wie "Running file" oder Erfolgsmeldungen aus. +- `--debug` zeigt zusätzlich Quelltext, Tokenliste, Type-Checking-Ergebnisse und den Ablauf der Interpretation. +- Fehler im Type Checker halten die Ausführung nicht auf – sie werden gemeldet, anschließend läuft der Interpreter weiter. + +## Analysewerkzeuge + +| Befehl | Zweck | +| --------------------------------- | ---------------------------------------------- | +| `hypnoscript lex ` | Zeigt alle Token mit Index, Typ und Lexem | +| `hypnoscript parse ` | Gibt den formatierten Abstract Syntax Tree aus | +| `hypnoscript check ` | Prüft Typen und meldet Inkonsistenzen | +| `hypnoscript compile-wasm ` | Generiert WebAssembly Text Format (`.wat`) | + +Diese Tools lassen sich ideal kombinieren, um Parser- oder Typfehler einzugrenzen. Beispiel: + +```bash +hypnoscript check scripts/report.hyp +hypnoscript parse scripts/report.hyp +hypnoscript compile-wasm scripts/report.hyp -o report.wat +``` + +## Standardbibliothek erkunden + +```bash +hypnoscript builtins +``` + +Der Befehl gruppiert alle eingebauten Funktionen nach Kategorie (Math, String, Array, System, ...). Nutze ihn, um schnell passende Helfer zu finden. + +## Typischer Workflow + +1. **Vorbereitung** – `hypnoscript check` auf allen Skripten laufen lassen. +2. **Fehleranalyse** – bei Problemen `lex` oder `parse` verwenden, um den konkreten Abschnitt zu inspizieren. +3. **Ausführung** – mit `run` testen, bei Bedarf `--debug` aktivieren. +4. **Deployment** – optional `compile-wasm`, wenn das Skript im Browser oder in einer WASM-Umgebung laufen soll. + +```bash +# Beispiel: komplette Runde +hypnoscript check examples/inventory.hyp +hypnoscript run examples/inventory.hyp --debug +hypnoscript compile-wasm examples/inventory.hyp -o inventory.wat +``` + +## Tipps & Tricks + +- **Schnelle Iteration:** Nutze `--debug`, sobald etwas merkwürdig wirkt – Token und AST verraten sofort, ob der Parser deine Absicht verstanden hat. +- **Ausgaben bündeln:** Pipe die Ausgabe in eine Datei (`hypnoscript run script.hyp > output.txt`), um längere Läufe zu dokumentieren. +- **Platform-agnostisch:** Unter Windows, macOS und Linux sind die Befehle identisch. Einzige Voraussetzung ist, dass der `hypnoscript`-Binary im `PATH` liegt. +- **Tests als Skripte:** Die Dateien im Ordner `hypnoscript-tests/` lassen sich direkt mit `hypnoscript run` starten. So siehst du reale Beispiele für Kontrollfluss und Sessions. + +## Weiterführende Links + +- [CLI Übersicht](../cli/overview) – Installation, Binary-Varianten und Workflow +- [CLI-Befehle](../cli/commands) – Vollständige Referenz mit allen Optionen +- [Sprachreferenz](../language-reference/syntax) – Detaillierte Beschreibung der Grammatik diff --git a/hypnoscript-docs/docs/getting-started/core-concepts.md b/hypnoscript-docs/docs/getting-started/core-concepts.md new file mode 100644 index 0000000..18f3d9b --- /dev/null +++ b/hypnoscript-docs/docs/getting-started/core-concepts.md @@ -0,0 +1,113 @@ +# Core Concepts + +Dieser Überblick fasst die wichtigsten Bausteine der aktuellen HypnoScript-Implementierung zusammen. Wenn du den Code oder die Tests im Repository liest, findest du genau diese Konzepte wieder. + +## Programmstruktur + +- **Focus/Relax**: Jedes Skript startet mit `Focus {` und endet mit `} Relax`. +- **`entrance`**: Optionaler Block direkt nach `Focus`, ideal für Setup und Begrüßung. +- **`finale`**: Optionaler Block vor `Relax`, wird immer ausgeführt (Cleanup). + +```hyp +Focus { + entrance { observe "Hallo"; } + // ... regulärer Code ... + finale { observe "Auf Wiedersehen"; } +} Relax +``` + +## Deklarationen & Typen + +- `induce name: string = "Text";` – veränderbare Variable. +- `implant` – Alias für `induce`. +- `freeze PI: number = 3.14159;` – Konstante. +- Arrays werden mit `[]` notiert: `induce values: number[] = [1, 2, 3];`. +- Unterstützte Typen: `number`, `string`, `boolean`, Arrays, Funktionen, Sessions. Ein `trance`-Typ existiert im Typsystem, wird aber derzeit nicht aktiv verwendet. + +## Kontrolle & Operatoren + +- `if`, `else if`, `else` +- `while` für bedingte Schleifen +- `loop { ... }` als endlose Schleife (Beenden via `snap`/`break`) +- `snap` (Alias `break`), `sink` (Alias `continue`) +- Hypnotische Operatoren wie `youAreFeelingVerySleepy` (`==`) oder `underMyControl` (`&&`) +- Booleans können mit `oscillate flag;` umgeschaltet werden + +## Funktionen + +- Definiert mit `suggestion name(params): returnType { ... }` +- `awaken` (oder `return`) beendet eine Funktion. +- Trigger verwenden `trigger name = suggestion(...) { ... }` und verhalten sich wie Callbacks. + +```hyp +suggestion greet(name: string) { + observe "Hallo, " + name + "!"; +} + +trigger onWelcome = suggestion(person: string) { + greet(person); +} +``` + +## Sessions (Objektorientierung) + +- `session Name { ... }` erzeugt eine Klasse. +- Felder: `expose` (öffentlich) oder `conceal` (privat). `dominant` macht Felder oder Methoden statisch. +- Methoden nutzen `suggestion`, `imperativeSuggestion` oder `dominantSuggestion` (Letzteres erzwingt statisch). +- Konstruktoren: `suggestion constructor(...) { ... }`. +- Der Interpreter injiziert `this` für Instanzmethoden und verhindert, dass statische Mitglieder über Instanzen angesprochen werden (und umgekehrt). + +```hyp +session Counter { + expose name: string; + conceal value: number = 0; + + suggestion constructor(name: string) { + this.name = name; + } + + expose suggestion increment() { + this.value = this.value + 1; + observe this.name + ": " + this.value; + } +} + +induce c: Counter = Counter("HypnoBot"); +c.increment(); +``` + +## Builtins + +Der Type Checker registriert sämtliche Standardfunktionen. Wichtige Kategorien: + +- **Mathe**: `Sin`, `Cos`, `Sqrt`, `Pow`, `Clamp`, `Factorial`, `Gcd`, `Lcm`, `IsPrime`, `Fibonacci`, … +- **Strings**: `Length`, `ToUpper`, `Trim`, `Replace`, `Split`, `Substring`, `PadLeft`, `IsWhitespace`, … +- **Arrays**: `ArrayLength`, `ArrayIsEmpty`, `ArraySum`, `ArrayAverage`, `ArraySlice`, `ArrayDistinct`, … +- **System & Dateien**: `GetOperatingSystem`, `GetUsername`, `GetArgs`, `ReadFile`, `WriteFile`, `ListDirectory`, … +- **Zeit & Statistik**: `CurrentTimestamp`, `CurrentDate`, `Mean`, `Median`, `StandardDeviation`, `Correlation`, … +- **Validierung & Utility**: `IsValidEmail`, `MatchesPattern`, `HashString`, `SimpleRandom`, … + +Alle Builtins gibt es kompakt per `hypnoscript builtins`. + +## CLI-Workflow + +```bash +hypnoscript lex file.hyp # Tokens anzeigen +hypnoscript parse file.hyp # AST inspizieren +hypnoscript check file.hyp # Typprüfung +hypnoscript run file.hyp # Ausführen +hypnoscript compile-wasm file.hyp -o file.wat +hypnoscript version # Toolchain-Infos +``` + +- `--debug` beim `run`-Befehl zeigt Zwischenschritte (Source, Tokens, Type Check). +- `--verbose` fügt zusätzliche Statusmeldungen hinzu. + +## Wo du weiterliest + +- [Quick Start](./quick-start) – Dein erstes Skript Schritt für Schritt +- [CLI Basics](./cli-basics) – Alle Subcommands im Detail +- [Syntax-Referenz](../language-reference/syntax) – Vollständige Grammatik +- [Builtin-Übersicht](../builtins/overview) – Alle Funktionen nach Kategorien + +Mit diesen Konzepten liest du den Repository-Code problemlos und kannst eigene Skripte schreiben. diff --git a/hypnoscript-docs/docs/getting-started/hello-world.md b/hypnoscript-docs/docs/getting-started/hello-world.md new file mode 100644 index 0000000..5d2a89c --- /dev/null +++ b/hypnoscript-docs/docs/getting-started/hello-world.md @@ -0,0 +1,93 @@ +--- +title: Hello World +sidebar_position: 3 +--- + +# Hello World + +Dein erstes HypnoScript-Programm! + +## Einfaches Hello World + +Erstelle eine Datei `hello.hyp` mit folgendem Inhalt: + +```hyp +Focus { + observe "Hallo Welt!"; +} Relax +``` + +Führe das Programm aus: + +```bash +hypnoscript hello.hyp +``` + +Ausgabe: + +``` +Hallo Welt! +``` + +## Mit Entrance-Block + +Der `entrance`-Block wird beim Programmstart ausgeführt: + +```hyp +Focus { + entrance { + observe "Willkommen in HypnoScript!"; + observe "Dies ist dein erstes Programm."; + } +} Relax +``` + +## Mit Variablen + +```hyp +Focus { + entrance { + induce name: string = "Entwickler"; + observe "Hallo, " + name + "!"; + observe "Willkommen bei HypnoScript."; + } +} Relax +``` + +## Interaktives Hello World + +```hyp +Focus { + entrance { + observe "=== HypnoScript Willkommens-Programm ==="; + + induce name: string = "Welt"; + induce version: number = 1.0; + + observe "Hallo, " + name + "!"; + observe "HypnoScript Version " + version; + observe "Bereit für hypnotische Programmierung!"; + } +} Relax +``` + +## Mit Funktionen + +```hyp +Focus { + suggestion greet(name: string) { + observe "Hallo, " + name + "!"; + observe "Schön, dich kennenzulernen."; + } + + entrance { + greet("HypnoScript-Entwickler"); + } +} Relax +``` + +## Nächste Schritte + +- Lerne über [Variablen und Datentypen](../language-reference/variables.md) +- Verstehe [Kontrollstrukturen](../language-reference/control-flow.md) +- Entdecke [Builtin-Funktionen](../builtins/overview.md) diff --git a/hypnoscript-docs/docs/getting-started/installation.md b/hypnoscript-docs/docs/getting-started/installation.md new file mode 100644 index 0000000..65e71f1 --- /dev/null +++ b/hypnoscript-docs/docs/getting-started/installation.md @@ -0,0 +1,90 @@ +--- +sidebar_position: 1 +--- + +# Installation + +Dieser Leitfaden führt dich durch die Installation der Rust-basierten HypnoScript-Toolchain. + +## Voraussetzungen + +| Komponente | Empfehlung | +| --------------- | -------------------------------------------------------------------------- | +| Betriebssystem | Windows 10+, macOS 12+, Linux (Ubuntu 20.04+, Fedora 38+, Arch) | +| Rust Toolchain | `rustup` mit Rust 1.76 oder neuer (`rustup --version` zur Kontrolle) | +| Build-Werkzeuge | Git, C/C++ Build-Tools (werden von `rustup` / Paketmanager bereitgestellt) | + +Optional für die Dokumentation: Node.js 18+. + +### Rust installieren + +```bash +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh + +# Nach der Installation ein neues Terminal öffnen und prüfen +rustc --version +cargo --version +``` + +Unter Windows empfiehlt sich alternativ der [rustup-init.exe Download](https://win.rustup.rs/). + +## HypnoScript aus dem Repository bauen (empfohlen) + +```bash +git clone https://github.com/Kink-Development-Group/hyp-runtime.git +cd hyp-runtime + +# Release-Build der CLI erzeugen +cargo build -p hypnoscript-cli --release + +# Optional global installieren (legt hypnoscript ins Cargo-Bin-Verzeichnis) +cargo install --path hypnoscript-cli +``` + +Die fertig gebaute CLI liegt anschließend unter `./target/release/hypnoscript` bzw. nach der Installation im Cargo-Bin-Verzeichnis (`~/.cargo/bin` bzw. `%USERPROFILE%\.cargo\bin`). + +## Vorbereitete Release-Pakete verwenden + +Wenn du nicht selbst bauen möchtest, findest du unter [GitHub Releases](https://github.com/Kink-Development-Group/hyp-runtime/releases) signierte Artefakte für Windows, macOS und Linux. Nach dem Entpacken kannst du die enthaltene Binärdatei direkt ausführen. + +## Installation prüfen + +```bash +# Version und verfügbare Befehle anzeigen +hypnoscript version +hypnoscript builtins + +# Minimales Testprogramm +echo 'Focus { entrance { observe "Installation erfolgreich!"; } } Relax' > test.hyp +hypnoscript run test.hyp +``` + +Erwartete Ausgabe (gekürzt): + +```text +HypnoScript v1.0.0 (Rust Edition) +Installation erfolgreich! +``` + +## Häufige Probleme + +| Problem | Lösung | +| ------------------------- | --------------------------------------------------------------------------------------------------- | +| `cargo` nicht gefunden | Prüfe, ob `~/.cargo/bin` (Linux/macOS) bzw. `%USERPROFILE%\.cargo\bin` (Windows) im `PATH` liegt. | +| Linker-Fehler unter Linux | Installiere Build-Abhängigkeiten (`sudo apt install build-essential` oder Distribution-Äquivalent). | +| Keine Ausführungsrechte | Setze `chmod +x hypnoscript` nach dem Entpacken eines Release-Artefakts. | + +## Optional: Entwicklungskomfort + +- **VS Code**: Installiere die Extensions _Rust Analyzer_ und _Even Better TOML_. Das Repo enthält eine `hyp-runtime.code-workspace`-Datei. +- **Shell Alias**: `alias hyp="hypnoscript"` für kürzere Befehle. +- **Dokumentation bauen**: `npm install` & `npm run dev` im Ordner `hypnoscript-docs`. + +## Nächste Schritte + +- [Quick Start](./quick-start) +- [CLI Basics](./cli-basics) +- [Sprachreferenz](../language-reference/syntax) +- [Standardbibliothek](../builtins/overview) + +Viel Spaß beim hypnotischen Coden! 🌀 diff --git a/hypnoscript-docs/docs/getting-started/quick-start.md b/hypnoscript-docs/docs/getting-started/quick-start.md new file mode 100644 index 0000000..566917a --- /dev/null +++ b/hypnoscript-docs/docs/getting-started/quick-start.md @@ -0,0 +1,177 @@ +--- +title: Quick Start +sidebar_position: 2 +--- + +Dieser Leitfaden setzt voraus, dass du HypnoScript gemäß [Installation](./installation) eingerichtet hast. Wir erstellen ein erstes Skript, führen es aus und streifen die wichtigsten Sprachelemente. + +## 1. Installation prüfen + +```bash +hypnoscript version +``` + +Der Befehl sollte Versions- und Featureinformationen ausgeben. + +## 2. Erstes Skript anlegen + +Speichere den folgenden Code als `hello_trance.hyp`: + +```hyp +Focus { + entrance { + observe "🌀 Willkommen in deiner ersten Hypnose-Session"; + } + + induce name: string = "Hypnotisierte Person"; + observe "Hallo, " + name + "!"; + + induce numbers: number[] = [1, 2, 3, 4, 5]; + induce total: number = ArraySum(numbers); + observe "Summe: " + ToString(total); + + if (total youAreFeelingVerySleepy 15) { + observe "Die Zahlen befinden sich im Gleichgewicht."; + } else { + observe "Etwas fühlt sich noch unstimmig an..."; + } + + induce depth: number = 0; + while (depth goingDeeper 3) { + observe "Trancetiefe: " + depth; + depth = depth + 1; + } +} Relax +``` + +Highlights: + +- `Focus { ... } Relax` markiert Start und Ende des Programms. +- `entrance` eignet sich für Initialisierung. +- `induce` deklariert Variablen mit optionaler Typannotation. +- Hypnotische Operatoren wie `youAreFeelingVerySleepy` (`==`) oder `goingDeeper` (`<=`) sind voll unterstützt. +- `ArraySum` und `ToString` stammen aus der Standardbibliothek. + +## 3. Skript ausführen + +```bash +hypnoscript run hello_trance.hyp +``` + +Die Ausgabe sollte die Begrüßung, die Summe und den kleinen While-Loop zeigen. + +## 4. Syntax in Kürze + +```hyp +Focus { + freeze PI: number = 3.14159; + + induce toggle: boolean = false; + oscillate toggle; // toggelt true/false + + suggestion hypnoticEcho(text: string): string { + awaken text + " ... tiefer ..."; + } + + observe hypnoticEcho("Atme ruhig"); + + session Subject { + expose name: string; + conceal depth: number; + + suggestion constructor(name: string) { + this.name = name; + this.depth = 0; + } + + expose suggestion deepen() { + this.depth = this.depth + 1; + observe this.name + " geht tiefer: " + this.depth; + } + } + + induce alice: Subject = Subject("Alice"); + alice.deepen(); +} Relax +``` + +## 5. Kontrollstrukturen + +```hyp +if (total lookAtTheWatch 10) { + observe "größer als 10"; +} else if (total youCannotResist 10) { + observe "ungleich 10"; +} else { + observe "genau 10"; +} + +while (depth fallUnderMySpell 5) { + depth = depth + 1; +} + +loop { + observe "Endlosschleife"; + snap; // beendet die Schleife +} +``` + +- `snap` ist Synonym für `break`. +- `sink` ist Synonym für `continue`. +- `deepFocus` kann nach der If-Bedingung stehen: `if (x > 0) deepFocus { ... }`. + +## 6. Funktionen und Trigger + +```hyp +suggestion add(a: number, b: number): number { + awaken a + b; +} + +trigger onClick = suggestion(label: string) { + observe "Trigger: " + label; +} + +observe ToString(add(2, 3)); +onClick("Demo"); +``` + +- `awaken` ist das hypnotische Pendant zu `return`. +- Trigger verhalten sich wie benannte Callback-Funktionen. Sie werden wie normale Funktionen aufgerufen. + +## 7. Arrays & Builtins + +```hyp +induce arr: number[] = [1, 2, 3]; +observe arr[0]; // Direktzugriff +arr[1] = 42; // Zuweisung + +observe ArrayLength(arr); // 3 +observe ArrayGet(arr, 2); // 3 +observe ArrayJoin(arr, ", "); +``` + +Weitere nützliche Funktionen: + +- Strings: `ToUpper`, `Trim`, `Split`, `Replace` +- Mathe: `Sqrt`, `Clamp`, `Factorial`, `IsPrime` +- System: `GetOperatingSystem`, `GetArgs` +- Dateien: `ReadFile`, `WriteFile`, `ListDirectory` + +Alle verfügbaren Builtins listet `hypnoscript builtins` auf. + +## 8. Häufige Fragen + +| Frage | Antwort | +| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | +| Warum endet alles mit `Relax`? | Der Relax-Block markiert das sichere Ausleiten – er ist fester Bestandteil der Grammatik. | +| Muss ich Typannotationen setzen? | Nein, aber sie verbessern Fehlermeldungen und die Autovervollständigung. | +| Gibt es for-Schleifen? | Nein. Nutze `while` oder `loop { ... snap; }` sowie Array-Builtins wie `ArrayForEach` existiert nicht – lieber eigene Funktionen schreiben. | + +## 9. Wie geht es weiter? + +- [Core Concepts](./core-concepts) – Konzepte und Toolchain im Überblick +- [CLI Basics](./cli-basics) – Alle Subcommands und Optionen +- [Sprachreferenz](../language-reference/syntax) – Ausführliche Grammatik & Beispiele +- [Builtin-Übersicht](../builtins/overview) – Funktionen nach Kategorien + +Viel Spaß beim Experimentieren mit HypnoScript! 🌀 diff --git a/hypnoscript-docs/docs/getting-started/what-is-hypnoscript.md b/hypnoscript-docs/docs/getting-started/what-is-hypnoscript.md new file mode 100644 index 0000000..d19de3f --- /dev/null +++ b/hypnoscript-docs/docs/getting-started/what-is-hypnoscript.md @@ -0,0 +1,93 @@ +# Was ist HypnoScript? + +HypnoScript ist eine statisch typisierte Skriptsprache mit hypnotischer Syntax. Statt `class`, `function` oder `print` findest du Begriffe wie `session`, `suggestion` und `observe`. Die Rust-basierte Implementierung liefert Lexer, Parser, Type Checker, Interpreter und einen WASM-Codegenerator in einem kompakten Toolchain-Bundle. + +## Designprinzipien + +- **Lesbarkeit vor allem** – Hypnotische Schlüsselwörter sollen Spaß machen, ohne die Verständlichkeit zu verlieren. +- **Statische Sicherheit** – Der Type Checker validiert Variablen, Funktionssignaturen, Rückgabewerte und Session-Mitglieder. +- **Deterministische Ausführung** – Der Interpreter führt Programme reproduzierbar aus und meldet Typfehler, bricht aber nicht zwangsläufig ab. +- **Ein Binary, alle Schritte** – Die CLI deckt Lexing, Parsing, Type Checking, Ausführung und optionales WASM-Target ab. + +## Sprache auf einen Blick + +| Element | Beschreibung | +| --------------------------------- | --------------------------------------------------------------------------------------------------- | +| `Focus { ... } Relax` | Umschließt jedes Programm. `Relax` markiert das Ende und ist obligatorisch. | +| `entrance { ... }` | Optionaler Startblock für Initialisierung, Begrüßung oder Setup. | +| `finale { ... }` | Optionaler Cleanup-Block, der vor `Relax` ausgeführt wird. | +| `induce` / `implant` | Deklariert veränderbare Variablen mit optionalem Typ. | +| `freeze` | Deklariert Konstanten. | +| `observe` / `whisper` / `command` | Ausgabe mit Zeilenumbruch, ohne Zeilenumbruch bzw. fett/imperativ. | +| `suggestion` | Definiert Funktionen; `awaken` (oder `return`) gibt Werte zurück. | +| `session` | Objektorientierte Strukturen mit `expose` (öffentlich), `conceal` (privat) und `dominant` (static). | +| `anchor` | Speichert den aktuellen Wert eines Ausdrucks für später. | +| `oscillate` | Toggle für boolesche Variablen. | +| `deepFocus` | Optionaler Zusatz hinter `if (...)` für etwas dramatischere Bedingungsblöcke. | + +## Beispielprogramm + +```hyp +Focus { + entrance { + observe "Willkommen bei HypnoScript"; + } + + freeze MAX_DEPTH: number = 3; + induce depth: number = 0; + + while (depth goingDeeper MAX_DEPTH) { + observe "Tiefe: " + depth; + depth = depth + 1; + } + + suggestion introduce(name: string): string { + awaken "Hallo, " + name + "!"; + } + + observe introduce("Hypnotisierte Person"); + + session Subject { + expose name: string; + conceal level: number; + + suggestion constructor(name: string) { + this.name = name; + this.level = 0; + } + + expose suggestion deepen() { + this.level = this.level + 1; + observe this.name + " geht tiefer: " + this.level; + } + } + + induce alice: Subject = Subject("Alice"); + alice.deepen(); +} Relax +``` + +## Plattform-Komponenten + +- **Lexer & Parser** – Liefern Token-Streams und ASTs, inkl. hypnotischer Operator-Synonyme (`youAreFeelingVerySleepy`, `underMyControl`, …). +- **Type Checker** – Registriert alle Builtins, prüft Funktions- und Sessionsignaturen, Sichtbarkeiten und Konversionen. +- **Interpreter** – Führt AST-Knoten aus, verwaltet Sessions, statische Felder, Trigger und Builtins. +- **WASM-Codegenerator** – Erstellt WebAssembly Text (.wat) für ausgewählte Konstrukte. +- **CLI** – `hypnoscript` vereint alle Schritte: `run`, `lex`, `parse`, `check`, `compile-wasm`, `builtins`, `version`. + +## Typische Einsatzfelder + +- **Skript-Experimente** – Kombination aus ungewöhnlicher Syntax und vertrauten Kontrollstrukturen. +- **Lehre & Workshops** – Zeigt, wie Parser, Type Checker und Interpreter zusammenarbeiten. +- **Tooling-Demos** – Beispiel dafür, wie eine Sprache komplett in Rust abgebildet werden kann. +- **Web-WASM-Experimente** – Programmteile nach `.wat` exportieren und in WebAssembly-Projekten einsetzen. + +## Weiterführende Ressourcen + +- [Core Concepts](./core-concepts) – Überblick über Sprachelemente, Typsystem und Runtime. +- [Installation](./installation) – Lokale Einrichtung der Toolchain. +- [Quick Start](./quick-start) – Dein erstes Skript in wenigen Minuten. +- [Sprachreferenz](../language-reference/syntax) – Grammatik, Operatoren, Funktionen, Sessions. +- [Builtin-Übersicht](../builtins/overview) – Alle Standardfunktionen nach Kategorien. + +HypnoScript macht hypnotische Metaphern programmierbar – mit einer ehrlichen Rust-Basis unter der Haube. diff --git a/hypnoscript-docs/docs/index.md b/hypnoscript-docs/docs/index.md new file mode 100644 index 0000000..da263f3 --- /dev/null +++ b/hypnoscript-docs/docs/index.md @@ -0,0 +1,117 @@ +--- +layout: home + +hero: + name: 'HypnoScript' + text: 'Die hypnotische Programmiersprache' + tagline: Moderne Skripte mit hypnotischer Syntax und einer soliden Rust-Basis + image: + src: /img/logo.svg + alt: HypnoScript Logo + actions: + - theme: brand + text: Schnellstart + link: /getting-started/quick-start + - theme: alt + text: Dokumentation + link: /intro + - theme: alt + text: GitHub + link: https://github.com/Kink-Development-Group/hyp-runtime + +features: + - icon: 🎯 + title: Hypnotische Syntax + details: Schlüsselwörter wie Focus, Relax, induce, observe oder deepFocus bringen hypnotische Metaphern direkt in deinen Code. + + - icon: 🦀 + title: Vollständig in Rust umgesetzt + details: Lexer, Parser, statischer Type Checker, Interpreter und WASM-Codegen laufen nativ auf Windows, macOS und Linux. + + - icon: 🧠 + title: Statisches Typ-System + details: Der Type Checker versteht Zahlen, Strings, Booleans, Arrays, Funktionen und Sessions inklusive Sichtbarkeiten. + + - icon: 📦 + title: Standardbibliothek inklusive + details: Mathe, Strings, Arrays, Dateien, Statistik, Systeminformationen, Zeit & Datum sowie Validierungsfunktionen sind sofort verfügbar. + + - icon: 🛠️ + title: Schlanke CLI + details: Ein einziges Binary liefert run, lex, parse, check, compile-wasm, builtins und version – mehr brauchst du nicht. + + - icon: 🧩 + title: Sessions mit Sichtbarkeit + details: Definiere Sessions mit `expose`/`conceal`, Konstruktoren und statischen (`dominant`) Mitgliedern. + + - icon: 🌐 + title: WebAssembly Export + details: Erzeuge optional WebAssembly Textdateien (.wat) und nutze HypnoScript im Browser. +--- + +## Schneller Einstieg + +### Installation + +```bash +# Repository klonen +git clone https://github.com/Kink-Development-Group/hyp-runtime.git +cd hyp-runtime + +# HypnoScript CLI in Release-Qualität bauen +cargo build -p hypnoscript-cli --release + +# Optional global installieren (binary heißt hypnoscript) +cargo install --path hypnoscript-cli +``` + +Fertige Artefakte (Windows, macOS, Linux) findest du außerdem im Ordner `release/` sowie unter [GitHub Releases](https://github.com/Kink-Development-Group/hyp-runtime/releases). + +### Dein erstes HypnoScript-Programm + +```hyp +Focus { + entrance { + observe "Willkommen bei HypnoScript!"; + } + + induce name: string = "Entwickler"; + observe "Hallo, " + name + "!"; + + induce numbers: number[] = [1, 2, 3, 4, 5]; + induce sum: number = ArraySum(numbers); + observe "Summe: " + ToString(sum); + + if (sum lookAtTheWatch 10) deepFocus { + observe "Die Erinnerung wird jetzt intensiver."; + } +} +``` + +### Ausführen + +```bash +hypnoscript run mein_script.hyp +``` + +## Warum HypnoScript? + +HypnoScript kombiniert die Eleganz moderner Programmiersprachen mit einer einzigartigen, hypnotisch inspirierten Syntax. Die Rust-Implementierung bringt dir: + +- **🎯 Einzigartige Syntax** – Focus/Relax-Blöcke, hypnotische Operatoren wie `youAreFeelingVerySleepy` (`==`) oder `underMyControl` (`&&`). +- **🦾 Rust-Performance** – Keine externen Laufzeitabhängigkeiten, schnelle Binaries und optionaler WASM-Export. +- **🔒 Statische Sicherheit** – Der Type Checker prüft Variablen, Funktionen, Sessions sowie Zugriffe auf statische und private Mitglieder. +- **🧰 Standardbibliothek** – Mathe, Strings, Arrays, Dateien, Statistik, Validierung, System- und Zeitfunktionen sind direkt integriert. +- **🧪 Entwicklungs-Workflow** – Die CLI unterstützt Lexing, Parsing, Type Checking und Programmausführung im gleichen Tool. +- **📄 Beispiele & Tests** – `.hyp`-Beispiele und Regressionstests im Repository zeigen reale Sprachfeatures. + +## Community & Support + +- **GitHub**: [Kink-Development-Group/hyp-runtime](https://github.com/Kink-Development-Group/hyp-runtime) +- **Dokumentation**: Diese Seite +- **Issues**: [GitHub Issues](https://github.com/Kink-Development-Group/hyp-runtime/issues) +- **Community Updates**: Verfolge den Fortschritt im [GitHub Repository](https://github.com/Kink-Development-Group/hyp-runtime) + +## Lizenz + +HypnoScript ist Open Source und unter der MIT-Lizenz verfügbar. diff --git a/hypnoscript-docs/docs/intro.md b/hypnoscript-docs/docs/intro.md new file mode 100644 index 0000000..18e1387 --- /dev/null +++ b/hypnoscript-docs/docs/intro.md @@ -0,0 +1,101 @@ +--- +sidebar_position: 1 +--- + +# Willkommen bei HypnoScript + +HypnoScript ist eine moderne, esoterische Programmiersprache, die hypnotische Metaphern mit einer pragmatischen Rust-Toolchain verbindet. Die Syntax erinnert an TypeScript, nutzt aber Schlüsselwörter wie `Focus`, `induce`, `observe` oder `Relax`, um hypnotische Konzepte direkt auszudrücken. + +## Was ist HypnoScript? + +Die aktuelle Runtime besteht vollständig aus Rust-Crates und liefert: + +- 🦀 **Native Toolchain** – Lexer, Parser, statischer Type Checker, Interpreter und WASM-Codegenerator sind vollständig in Rust implementiert. +- 🎯 **Hypnotische Syntax** – Sprachkonstrukte wie `deepFocus`, `snap`, `anchor` oder `oscillate` übersetzen hypnotische Bilder in Code. +- 🔒 **Statisches Typ-System** – Der Type Checker kennt Zahlen, Strings, Booleans, Arrays, Funktionen und Sessions inklusive Sichtbarkeiten. +- 📦 **Standardbibliothek** – Mathe-, String-, Array-, Datei-, Statistik-, System-, Zeit- und Validierungs-Builtins stehen direkt bereit. +- 🛠️ **CLI für den gesamten Workflow** – Ein einzelnes Binary (`hypnoscript`) bietet `run`, `lex`, `parse`, `check`, `compile-wasm`, `builtins` und `version`. + +Die Sprache ist plattformübergreifend (Windows/macOS/Linux) und erzeugt native Binaries sowie optional WebAssembly-Ausgabe. + +## Grundelemente der Syntax + +| Konzept | Beschreibung | +| ---------------------- | -------------------------------------------------------------------------------------------------------- | +| `Focus { ... } Relax` | Umschließt jedes Programm (Entry- und Exit-Punkt). | +| `entrance { ... }` | Optionaler Startblock für Initialisierung oder Begrüßung. | +| `finale { ... }` | Optionaler Cleanup-Block, der am Ende garantiert ausgeführt wird. | +| `induce` / `freeze` | Deklariert Variablen (`induce`/`implant`) oder Konstanten (`freeze`). | +| `observe` / `whisper` | Ausgabe mit bzw. ohne Zeilenumbruch. `command` hebt Text emphatisch hervor. | +| `if`, `while`, `loop` | Kontrollstrukturen mit hypnotischen Operator-Synonymen (`youAreFeelingVerySleepy`, `underMyControl`, …). | +| `suggestion` | Funktionsdefinition (global oder innerhalb von Sessions). | +| `session` | Objektorientierte Strukturen mit Feldern (`expose`/`conceal`), Konstruktoren und statischen Mitgliedern. | +| `anchor` / `oscillate` | Speichert Werte zwischen oder toggelt Booleans. | + +```hyp +Focus { + entrance { + observe "Willkommen in der Trance"; + } + + induce counter: number = 0; + while (counter goingDeeper 3) { + observe "Tiefe: " + counter; + counter = counter + 1; + } + + suggestion hypnoticSum(values: number[]): number { + awaken ArraySum(values); + } + + observe "Summe: " + ToString(hypnoticSum([2, 4, 6])); +} Relax +``` + +## Standardbibliothek im Überblick + +Die Builtins sind in Kategorien organisiert. Eine detaillierte Referenz findest du unter [Standardbibliothek](./builtins/overview). + +- **Mathematik** – `Sin`, `Cos`, `Tan`, `Sqrt`, `Pow`, `Factorial`, `Clamp`, `Gcd`, `Lcm`, `IsPrime`, `Fibonacci`, … +- **Strings** – `Length`, `ToUpper`, `ToLower`, `Trim`, `Reverse`, `Replace`, `Split`, `Substring`, `PadLeft`, `IsWhitespace`, … +- **Arrays** – `ArrayLength`, `ArrayIsEmpty`, `ArraySum`, `ArrayAverage`, `ArraySlice`, `ArrayDistinct`, … +- **Dateien** – `ReadFile`, `WriteFile`, `AppendFile`, `ListDirectory`, `GetFileExtension`, … +- **System** – `GetOperatingSystem`, `GetUsername`, `GetArgs`, `Exit`, `GetCurrentDirectory`, … +- **Zeit & Datum** – `CurrentTimestamp`, `CurrentDateTime`, `IsLeapYear`, `DayOfWeek`, … +- **Statistik** – `Mean`, `Median`, `Mode`, `StandardDeviation`, `Correlation`, `LinearRegression`, … +- **Validierung** – `IsValidEmail`, `MatchesPattern`, `IsInRange`, `IsNumeric`, `IsLowercase`, … +- **Hypnotische Kernfunktionen** – `Observe`, `Whisper`, `Command`, `Drift`, `DeepTrance`, `HypnoticCountdown`, `TranceInduction`, `HypnoticVisualization`. + +## Entwicklungs-Workflow + +```bash +# Quelle lesen, lexen, parsen, checken und ausführen +hypnoscript lex examples/test.hyp +hypnoscript parse examples/test.hyp +hypnoscript check examples/test.hyp +hypnoscript run examples/test.hyp + +# Zu WebAssembly (wat) generieren +hypnoscript compile-wasm examples/test.hyp --output output.wat + +# Listing aller Builtins +hypnoscript builtins +``` + +Der Interpreter führt Programme deterministisch aus. Typprüfungsfehler werden gemeldet, blockieren die Ausführung aber nicht – ideal für exploratives Arbeiten. + +## Nächste Schritte + +- [Installation](./getting-started/installation) +- [Quick Start](./getting-started/quick-start) +- [Grundkonzepte](./getting-started/core-concepts) +- [Sprachreferenz](./language-reference/syntax) +- [Standardbibliothek](./builtins/overview) + +## Community & Lizenz + +- GitHub: [Kink-Development-Group/hyp-runtime](https://github.com/Kink-Development-Group/hyp-runtime) +- Issues & Roadmap: [GitHub Issues](https://github.com/Kink-Development-Group/hyp-runtime/issues) +- Lizenz: [MIT](https://opensource.org/license/mit/) + +Tauche ein, hypnotisiere deinen Code und genieße eine Sprache, die humorvollen Flair mit ernstzunehmender Infrastruktur verbindet. 🧠✨ diff --git a/hypnoscript-docs/docs/language-reference/_keywords-reference.md b/hypnoscript-docs/docs/language-reference/_keywords-reference.md new file mode 100644 index 0000000..92e82a5 --- /dev/null +++ b/hypnoscript-docs/docs/language-reference/_keywords-reference.md @@ -0,0 +1,166 @@ +# Schlüsselwörter-Referenz + +Vollständige Referenz aller Schlüsselwörter in HypnoScript basierend auf der Rust-Implementierung. + +## Programmstruktur + +| Schlüsselwort | Beschreibung | Beispiel | +| ------------- | --------------------------------------- | ------------------------------- | +| `Focus` | Programmstart (erforderlich) | `Focus { ... } Relax` | +| `Relax` | Programmende (erforderlich) | `Focus { ... } Relax` | +| `entrance` | Initialisierungsblock (optional) | `entrance { observe "Start"; }` | +| `finale` | Cleanup/Destruktor-Block (optional) | `finale { observe "Ende"; }` | +| `deepFocus` | Erweiterter if-Block mit tieferer Scope | `if (x > 5) deepFocus { ... }` | + +## Variablendeklarationen + +| Schlüsselwort | Beschreibung | Mutabilität | Beispiel | +| ------------- | -------------------------------- | ------------- | ------------------------------------ | +| `induce` | Standard-Variablendeklaration | Veränderbar | `induce x: number = 42;` | +| `implant` | Alternative Variablendeklaration | Veränderbar | `implant y: string = "text";` | +| `freeze` | Konstanten-Deklaration | Unveränderbar | `freeze PI: number = 3.14159;` | +| `anchor` | State Snapshot/Backup erstellen | Unveränderbar | `anchor saved = currentValue;` | +| `from` | Eingabe-Quellangabe | - | `induce x: number from external;` | +| `external` | Externe Eingabequelle | - | `induce name: string from external;` | + +## Kontrollstrukturen + +| Schlüsselwort | Beschreibung | Äquivalent | Beispiel | +| ------------- | ------------------------ | ---------- | ------------------------------------------------ | +| `if` | Bedingte Anweisung | if | `if (x > 5) { ... }` | +| `else` | Alternative Verzweigung | else | `if (x > 5) { ... } else { ... }` | +| `while` | While-Schleife | while | `while (x > 0) { x = x - 1; }` | +| `loop` | For-ähnliche Schleife | for | `loop (induce i = 0; i < 10; i = i + 1) { ... }` | +| `snap` | Schleife abbrechen | break | `while (true) { snap; }` | +| `sink` | Zum nächsten Durchlauf | continue | `while (x < 10) { sink; }` | +| `sinkTo` | Goto (zu Label springen) | goto | `sinkTo myLabel;` | +| `oscillate` | Boolean-Variable togglen | - | `oscillate isActive;` | + +**Hinweis:** `break` und `continue` werden auch als Synonyme für `snap` und `sink` akzeptiert. + +## Funktionen + +| Schlüsselwort | Beschreibung | Beispiel | +| ---------------------- | ------------------------------- | ------------------------------------------------------ | +| `suggestion` | Funktionsdeklaration | `suggestion add(a: number, b: number): number { ... }` | +| `trigger` | Event-Handler/Callback-Funktion | `trigger onClick = suggestion() { ... };` | +| `imperativeSuggestion` | Imperative Funktion (Modifier) | `imperativeSuggestion doSomething() { ... }` | +| `dominantSuggestion` | Statische Funktion (Modifier) | `dominantSuggestion helperFunc() { ... }` | +| `awaken` | Return-Statement | `awaken x + y;` | +| `call` | Expliziter Funktionsaufruf | `call myFunction();` | + +**Hinweis:** `return` wird auch als Synonym für `awaken` akzeptiert. + +## Objektorientierung + +### Sessions (Klassen) + +| Schlüsselwort | Beschreibung | Beispiel | +| ------------- | -------------------- | ---------------------------------------------- | +| `session` | Klassendeklaration | `session Person { ... }` | +| `constructor` | Konstruktor-Methode | `suggestion constructor(name: string) { ... }` | +| `expose` | Public-Sichtbarkeit | `expose name: string;` | +| `conceal` | Private-Sichtbarkeit | `conceal age: number;` | +| `dominant` | Statischer Member | `dominant counter: number = 0;` | + +### Strukturen + +| Schlüsselwort | Beschreibung | Beispiel | +| ------------- | ------------------------- | ------------------------------------------- | +| `tranceify` | Record/Struct-Deklaration | `tranceify Point { x: number; y: number; }` | + +## Ein-/Ausgabe + +| Schlüsselwort | Beschreibung | Verhalten | Beispiel | +| ------------- | -------------------- | --------------------------- | ----------------------------------- | +| `observe` | Standard-Ausgabe | Mit Zeilenumbruch | `observe "Hallo Welt";` | +| `whisper` | Ausgabe ohne Umbruch | Ohne Zeilenumbruch | `whisper "Teil1"; whisper "Teil2";` | +| `command` | Imperative Ausgabe | Großbuchstaben, mit Umbruch | `command "Wichtig!";` | +| `drift` | Pause/Sleep | Verzögerung in ms | `drift(2000);` | + +## Module und Globals + +| Schlüsselwort | Beschreibung | Beispiel | +| -------------- | ----------------- | ----------------------------------------- | +| `mindLink` | Import/Include | `mindLink "utilities.hyp";` | +| `sharedTrance` | Globale Variable | `sharedTrance config: string = "global";` | +| `label` | Label-Deklaration | `label myLabel;` | + +## Datentypen + +| Schlüsselwort | Beschreibung | Beispiel | +| ------------- | --------------------- | -------------------------------- | +| `number` | Numerischer Typ | `induce x: number = 42;` | +| `string` | String-Typ | `induce text: string = "hello";` | +| `boolean` | Boolean-Typ | `induce flag: boolean = true;` | +| `trance` | Spezieller Trance-Typ | `induce state: trance;` | + +## Literale + +| Schlüsselwort | Beschreibung | Beispiel | +| ------------- | --------------- | ----------------------------------- | +| `true` | Boolean-Literal | `induce isActive: boolean = true;` | +| `false` | Boolean-Literal | `induce isActive: boolean = false;` | + +## Testing/Debugging + +| Schlüsselwort | Beschreibung | Beispiel | +| ------------- | ------------ | --------------- | +| `assert` | Assertion | `assert x > 0;` | + +## Hypnotische Operatoren + +### Vergleichsoperatoren + +| Hypnotisch | Standard | Bedeutung | +| ------------------------- | -------- | -------------- | +| `youAreFeelingVerySleepy` | `==` | Gleich | +| `youCannotResist` | `!=` | Ungleich | +| `lookAtTheWatch` | `>` | Größer | +| `fallUnderMySpell` | `<` | Kleiner | +| `yourEyesAreGettingHeavy` | `>=` | Größer gleich | +| `goingDeeper` | `<=` | Kleiner gleich | + +### Legacy-Operatoren (veraltet, aber unterstützt) + +| Hypnotisch | Standard | Hinweis | +| --------------- | -------- | ---------------------------------- | +| `notSoDeep` | `!=` | Verwende `youCannotResist` | +| `deeplyGreater` | `>=` | Verwende `yourEyesAreGettingHeavy` | +| `deeplyLess` | `<=` | Verwende `goingDeeper` | + +### Logische Operatoren + +| Hypnotisch | Standard | Bedeutung | +| -------------------- | -------- | -------------- | +| `underMyControl` | `&&` | Logisches UND | +| `resistanceIsFutile` | `\|\|` | Logisches ODER | + +## Verwendungshinweise + +### Case-Insensitivity + +Alle Schlüsselwörter sind **case-insensitive** beim Lexing, werden aber zu ihrer kanonischen Form normalisiert: + +```hyp +// Alle folgenden sind äquivalent: +Focus { ... } Relax +focus { ... } relax +FOCUS { ... } RELAX +``` + +### Standard-Synonyme + +Für bessere Lesbarkeit unterstützt HypnoScript Standard-Synonyme: + +- `return` → `awaken` +- `break` → `snap` +- `continue` → `sink` + +### Empfehlungen + +1. **Verwende kanonische Formen** für bessere Lesbarkeit +2. **Nutze hypnotische Operatoren** für thematische Konsistenz +3. **Vermeide Legacy-Operatoren** (`notSoDeep`, `deeplyGreater`, `deeplyLess`) +4. **Bevorzuge `induce`** gegenüber `implant` für Standardvariablen +5. **Nutze `freeze`** für unveränderbare Werte statt `induce` diff --git a/HypnoScript.Dokumentation/docs/language-reference/arrays.md b/hypnoscript-docs/docs/language-reference/arrays.md similarity index 100% rename from HypnoScript.Dokumentation/docs/language-reference/arrays.md rename to hypnoscript-docs/docs/language-reference/arrays.md diff --git a/HypnoScript.Dokumentation/docs/language-reference/assertions.md b/hypnoscript-docs/docs/language-reference/assertions.md similarity index 100% rename from HypnoScript.Dokumentation/docs/language-reference/assertions.md rename to hypnoscript-docs/docs/language-reference/assertions.md diff --git a/HypnoScript.Dokumentation/docs/language-reference/control-flow.md b/hypnoscript-docs/docs/language-reference/control-flow.md similarity index 100% rename from HypnoScript.Dokumentation/docs/language-reference/control-flow.md rename to hypnoscript-docs/docs/language-reference/control-flow.md diff --git a/HypnoScript.Dokumentation/docs/language-reference/functions.md b/hypnoscript-docs/docs/language-reference/functions.md similarity index 100% rename from HypnoScript.Dokumentation/docs/language-reference/functions.md rename to hypnoscript-docs/docs/language-reference/functions.md diff --git a/hypnoscript-docs/docs/language-reference/operators.md b/hypnoscript-docs/docs/language-reference/operators.md new file mode 100644 index 0000000..08c2dbd --- /dev/null +++ b/hypnoscript-docs/docs/language-reference/operators.md @@ -0,0 +1,234 @@ +# Operatoren + +HypnoScript unterstützt Standard-Operatoren sowie hypnotische Synonyme für vergleichende und logische Operatoren. Alle Operatoren sind in der Rust-Implementierung vollständig typsicher. + +## Arithmetische Operatoren + +| Operator | Bedeutung | Typ-Anforderung | Beispiel | Ergebnis | +| -------- | -------------- | --------------- | -------- | -------- | +| + | Addition | number | 2 + 3 | 5 | +| - | Subtraktion | number | 5 - 2 | 3 | +| \* | Multiplikation | number | 4 \* 2 | 8 | +| / | Division | number | 8 / 2 | 4 | +| % | Modulo (Rest) | number | 7 % 3 | 1 | + +**String-Konkatenation:** Der `+` Operator funktioniert auch für Strings: + +```hyp +induce text: string = "Hallo " + "Welt"; // "Hallo Welt" +induce mixed: string = "Zahl: " + 42; // "Zahl: 42" +``` + +## Vergleichsoperatoren + +### Standard-Operatoren + +| Operator | Bedeutung | Beispiel | Ergebnis | +| -------- | -------------- | -------- | -------- | +| == | Gleich | 3 == 3 | true | +| != | Ungleich | 3 != 4 | true | +| > | Größer | 5 > 2 | true | +| < | Kleiner | 2 < 5 | true | +| >= | Größer gleich | 3 >= 2 | true | +| <= | Kleiner gleich | 2 <= 2 | true | + +### Hypnotische Synonyme + +HypnoScript bietet hypnotische Synonyme für alle Vergleichsoperatoren: + +| Hypnotisches Synonym | Standard | Bedeutung | Status | +| ----------------------- | -------- | -------------- | ------------ | +| youAreFeelingVerySleepy | == | Gleich | ✅ Empfohlen | +| youCannotResist | != | Ungleich | ✅ Empfohlen | +| lookAtTheWatch | > | Größer | ✅ Empfohlen | +| fallUnderMySpell | < | Kleiner | ✅ Empfohlen | +| yourEyesAreGettingHeavy | >= | Größer gleich | ✅ Empfohlen | +| goingDeeper | <= | Kleiner gleich | ✅ Empfohlen | + +**Legacy-Operatoren** (veraltet, aber unterstützt): + +| Hypnotisches Synonym | Standard | Hinweis | +| -------------------- | -------- | ------------------------------------------------- | +| notSoDeep | != | ⚠️ Verwende stattdessen `youCannotResist` | +| deeplyGreater | >= | ⚠️ Verwende stattdessen `yourEyesAreGettingHeavy` | +| deeplyLess | <= | ⚠️ Verwende stattdessen `goingDeeper` | + +## Logische Operatoren + +### Standard-Operatoren + +| Operator | Bedeutung | Beispiel | Ergebnis | +| -------- | --------- | --------------- | -------- | +| && | Und | true && false | false | +| \|\| | Oder | true \|\| false | true | +| ! | Nicht | !true | false | + +### Hypnotische Synonyme + +| Hypnotisches Synonym | Standard | Bedeutung | +| -------------------- | -------- | -------------- | +| underMyControl | && | Logisches UND | +| resistanceIsFutile | \|\| | Logisches ODER | + +**Hinweis:** Es gibt kein hypnotisches Synonym für den `!` (Nicht)-Operator. + +## Priorität der Operatoren + +Von höchster zu niedrigster Priorität: + +1. **Unäre Operatoren:** `!`, `-` (negativ) +2. **Multiplikativ:** `*`, `/`, `%` +3. **Additiv:** `+`, `-` +4. **Vergleich:** `<`, `<=`, `>`, `>=` (und hypnotische Synonyme) +5. **Gleichheit:** `==`, `!=` (und hypnotische Synonyme) +6. **Logisches UND:** `&&` (oder `underMyControl`) +7. **Logisches ODER:** `||` (oder `resistanceIsFutile`) + +Verwende Klammern `( )` für explizite Gruppierung. + +## Array-Zugriff und Zuweisung + +Arrays werden mit eckigen Klammern `[ ]` indiziert (0-basiert): + +```hyp +induce arr: number[] = [10, 20, 30]; +observe arr[0]; // Ausgabe: 10 +observe arr[2]; // Ausgabe: 30 + +arr[1] = 42; // Zuweisung +observe arr[1]; // Ausgabe: 42 +``` + +Für erweiterte Array-Operationen siehe [Array Builtin-Funktionen](../builtins/array-functions). + +## Zuweisungsoperator + +Der einfache Zuweisungsoperator `=` wird für Zuweisungen verwendet: + +```hyp +induce x: number = 5; +x = x + 1; // 6 +x = 10; // Neuzuweisung +``` + +**Wichtig:** Zusammengesetzte Zuweisungsoperatoren (`+=`, `-=`, `*=`, etc.) sind **nicht implementiert**. + +Verwende stattdessen: + +````hyp +// FALSCH: x += 5; +// RICHTIG: +x = x + 5; + +## Beispiele + +### Standard-Operatoren + +```hyp +Focus { + entrance { + induce a: number = 10; + induce b: number = 3; + + observe "a + b = " + (a + b); // 13 + observe "a - b = " + (a - b); // 7 + observe "a * b = " + (a * b); // 30 + observe "a / b = " + (a / b); // 3.333... + observe "a % b = " + (a % b); // 1 + + observe "a == b: " + (a == b); // false + observe "a > b: " + (a > b); // true + observe "a <= 10: " + (a <= 10); // true + } +} Relax +```` + +### Hypnotische Synonyme + +```hyp +Focus { + entrance { + induce x: number = 10; + induce y: number = 10; + + if (x youAreFeelingVerySleepy y) { + observe "x ist gleich y!"; + } + + if (x lookAtTheWatch 5 underMyControl y yourEyesAreGettingHeavy 8) { + observe "Beide Bedingungen sind wahr!"; + } + + if (x fallUnderMySpell 20 resistanceIsFutile y youAreFeelingVerySleepy 10) { + observe "Mindestens eine Bedingung ist wahr!"; + } + } +} Relax +``` + +### Array-Operationen + +```hyp +Focus { + entrance { + induce numbers: number[] = [1, 2, 3, 4, 5]; + + observe "Erstes Element: " + numbers[0]; + observe "Array-Länge: " + ArrayLength(numbers); + + numbers[2] = 99; + observe "Geändertes Element: " + numbers[2]; + } +} Relax +``` + +### Operatorkombinationen + +```hyp +Focus { + entrance { + induce x: number = 10; + induce y: number = 20; + induce z: number = 5; + + // Komplexe Ausdrücke mit Prioritäten + induce result1: number = x + y * z; // 110 (Multiplikation zuerst) + induce result2: number = (x + y) * z; // 150 (Klammern zuerst) + + observe "result1 = " + result1; + observe "result2 = " + result2; + + // Logische Operatoren kombinieren + if (x lookAtTheWatch 5 underMyControl y lookAtTheWatch 15) { + observe "x > 5 UND y > 15"; + } + + if (x fallUnderMySpell 5 resistanceIsFutile y yourEyesAreGettingHeavy 20) { + observe "x < 5 ODER y >= 20"; + } + + // Negation + induce isActive: boolean = true; + if (!isActive) { + observe "Nicht aktiv"; + } else { + observe "Aktiv"; + } + } +} Relax +``` + +## Best Practices + +1. **Verwende Klammern** bei komplexen Ausdrücken für bessere Lesbarkeit +2. **Nutze hypnotische Operatoren** konsequent für thematische Konsistenz +3. **Vermeide Legacy-Operatoren** (`notSoDeep`, `deeplyGreater`, `deeplyLess`) +4. **Typ-Konsistenz** beachten: Vergleiche nur Werte gleichen Typs +5. **Explizite Konvertierung** wenn nötig mit Builtin-Funktionen (`ToInt`, `ToDouble`, `ToString`) + +## Siehe auch + +- [Variablen](./variables) - Variablendeklaration und -zuweisung +- [Kontrollstrukturen](./control-flow) - if, while, loop +- [Builtin-Funktionen](../builtins/overview) - Verfügbare Standardfunktionen +- [Syntax](./syntax) - Vollständige Sprachsyntax diff --git a/HypnoScript.Dokumentation/docs/language-reference/records.md b/hypnoscript-docs/docs/language-reference/records.md similarity index 100% rename from HypnoScript.Dokumentation/docs/language-reference/records.md rename to hypnoscript-docs/docs/language-reference/records.md diff --git a/hypnoscript-docs/docs/language-reference/sessions.md b/hypnoscript-docs/docs/language-reference/sessions.md new file mode 100644 index 0000000..1ab1011 --- /dev/null +++ b/hypnoscript-docs/docs/language-reference/sessions.md @@ -0,0 +1,128 @@ +--- +title: Sessions +--- + +# Sessions + +Sessions are HypnoScript's object-oriented building blocks. They bundle related state and behaviour while keeping the hypnotic syntax you already know. This page explains how to declare sessions, control visibility, wire constructors, and work with static members. + +## Declaring a session + +A session groups fields and methods inside a dedicated block: + +```hypnoscript +session Account { + conceal balance: number = 0; + + expose suggestion constructor(initialBalance: number) { + this.balance = initialBalance; + } + + expose suggestion deposit(amount: number) { + this.balance = this.balance + amount; + } + + conceal suggestion snapshot(): number { + awaken this.balance; + } +} +``` + +Key points: + +- `session Name { ... }` declares the type. +- Fields require an explicit visibility keyword (`expose` for public, `conceal` for private). Initialisers are optional. +- Methods use `suggestion`, `imperativeSuggestion`, or `dominant suggestion` depending on the style you prefer. The parser treats `imperativeSuggestion` as an instance method and `dominant suggestion` as static. +- The optional `constructor` keyword after `suggestion` marks a constructor. Constructors cannot be static and always return an instance of the surrounding session. The type checker enforces those rules. + +## Field visibility + +Visibility determines where a member can be accessed: + +- `expose` marks a field or method as public. Public members can be used from any script. +- `conceal` restricts access to the defining session. Both the interpreter and the type checker reject external reads, writes, or calls. + +Attempting to reach a concealed member outside its session triggers a type error: + +```hypnoscript +Focus { + session Vault { + conceal pin: number = 1234; + expose suggestion reveal(): number { + awaken this.pin; + } + } + + induce vault = Vault(); + induce leak = vault.pin; // Field 'pin' of session 'Vault' is not visible here +} Relax +``` + +## Methods and constructors + +Instance methods rely on `this`, which the runtime binds automatically when you call them on an instance. Mark a constructor with `suggestion constructor(...)` and optionally accept parameters: + +```hypnoscript +session Timeline { + conceal events: number = 0; + + expose suggestion constructor(initial: number) { + this.events = initial; + } + + expose suggestion record(amount: number) { + this.events = this.events + amount; + } + + conceal suggestion current(): number { + awaken this.events; + } +} + +Focus { + induce timeline = Timeline(5); + timeline.record(3); + induce count = timeline.current(); +} Relax +``` + +The type checker validates constructor arity and ensures returns inside methods agree with the declared return type. + +## Static members + +Use the `dominant` modifier to mark members as static. Static fields belong to the session itself, not to individual instances, and must be accessed through the session name: + +```hypnoscript +session Config { + dominant expose version: string = "1.0"; + + dominant suggestion setVersion(next: string) { + Config.version = next; + } +} + +Focus { + Config.setVersion("2.1"); + induce activeVersion: string = Config.version; +} Relax +``` + +Static rules enforced by the compiler: + +- Assign static fields via the session (`Config.version = ...`), not through an instance. +- Do not call instance methods on the session type (`Config.update()` fails unless `update` is static). +- Constructors are always instance members and cannot be declared `dominant`. + +## Summary of type checker guarantees + +The extended type checker performs the following validations for sessions: + +- Detects duplicate fields, methods, or constructors inside a session. +- Ensures private members stay hidden outside the declaring session. +- Verifies constructors are unique, non-static, and called with the correct number of arguments. +- Differentiates static and instance members for both access and assignment. +- Catches `this` usage in static methods and invalid member assignments (for example, writing to methods). + +## Further reading + +Head over to [Basic Examples](/examples/basic-examples) for end-to-end snippets that combine constructors, static members, and visibility. The interpreter and runtime design notes in `/docs/reference/interpreter.md` highlight how the execution engine enforces the same constraints at runtime. diff --git a/HypnoScript.Dokumentation/docs/language-reference/syntax.md b/hypnoscript-docs/docs/language-reference/syntax.md similarity index 86% rename from HypnoScript.Dokumentation/docs/language-reference/syntax.md rename to hypnoscript-docs/docs/language-reference/syntax.md index 6d385a6..46090e8 100644 --- a/HypnoScript.Dokumentation/docs/language-reference/syntax.md +++ b/hypnoscript-docs/docs/language-reference/syntax.md @@ -15,7 +15,7 @@ Jedes HypnoScript-Programm beginnt mit `Focus` und endet mit `Relax`: ```hyp Focus { // Programm-Code hier -} Relax; +} Relax ``` ### Entrance-Block @@ -27,27 +27,27 @@ Focus { entrance { observe "Programm gestartet"; } -} Relax; +} Relax ``` ## Variablen und Zuweisungen -### Induce (Variablenzuweisung) +### Induce (Variablendeklaration) -Verwende `induce` um Variablen zu erstellen und Werte zuzuweisen: +Verwende `induce` um Variablen zu deklarieren und Werte zuzuweisen. Typ-Annotationen sind optional aber empfohlen: ```hyp Focus { entrance { - induce name = "HypnoScript"; - induce version = 1.0; - induce isActive = true; + induce name: string = "HypnoScript"; + induce version: number = 1.0; + induce isActive: boolean = true; observe "Name: " + name; observe "Version: " + version; observe "Aktiv: " + isActive; } -} Relax; +} Relax ``` ### Datentypen @@ -58,27 +58,23 @@ HypnoScript unterstützt verschiedene Datentypen: Focus { entrance { // Strings - induce text = "Hallo Welt"; + induce text: string = "Hallo Welt"; - // Zahlen (Integer und Double) - induce integer = 42; - induce decimal = 3.14159; + // Zahlen (nur number Typ) + induce integer: number = 42; + induce decimal: number = 3.14159; // Boolean - induce flag = true; + induce flag: boolean = true; // Arrays - induce numbers = [1, 2, 3, 4, 5]; - induce names = ["Alice", "Bob", "Charlie"]; + induce numbers: number[] = [1, 2, 3, 4, 5]; + induce names: string[] = ["Alice", "Bob", "Charlie"]; - // Records (Objekte) - induce person = { - name: "Max", - age: 30, - city: "Berlin" - }; + // Records (mit tranceify definiert) + // Siehe Records-Dokumentation für Details } -} Relax; +} Relax ``` ## Ausgabe @@ -93,10 +89,10 @@ Focus { observe "Einfache Ausgabe"; observe "Mehrzeilige" + " " + "Ausgabe"; - induce name = "HypnoScript"; + induce name: string = "HypnoScript"; observe "Willkommen bei " + name; } -} Relax; +} Relax ``` ## Kontrollstrukturen @@ -106,7 +102,7 @@ Focus { ```hyp Focus { entrance { - induce age = 18; + induce age: number = 18; if (age >= 18) { observe "Volljährig"; @@ -115,7 +111,7 @@ Focus { } // Mit else if - induce score = 85; + induce score: number = 85; if (score >= 90) { observe "Ausgezeichnet"; } else if (score >= 80) { @@ -126,7 +122,7 @@ Focus { observe "Verbesserungsbedarf"; } } -} Relax; +} Relax ``` ### While-Schleife @@ -134,55 +130,55 @@ Focus { ```hyp Focus { entrance { - induce counter = 1; + induce counter: number = 1; while (counter <= 5) { observe "Zähler: " + counter; - induce counter = counter + 1; + counter = counter + 1; } } -} Relax; +} Relax ``` -### For-Schleife +### Loop-Schleife ```hyp Focus { entrance { - // For-Schleife mit Range - for (induce i = 1; i <= 10; induce i = i + 1) { + // Loop-Schleife mit Zähler + loop (induce i: number = 1; i <= 10; i = i + 1) { observe "Iteration " + i; } - // For-Schleife über Array - induce fruits = ["Apfel", "Banane", "Orange"]; - for (induce i = 0; i < ArrayLength(fruits); induce i = i + 1) { + // Loop-Schleife über Array mit ArrayLength + induce fruits: string[] = ["Apfel", "Birne", "Kirsche"]; + loop (induce i: number = 0; i < ArrayLength(fruits); i = i + 1) { observe "Frucht " + (i + 1) + ": " + ArrayGet(fruits, i); } } -} Relax; +} Relax ``` ## Funktionen -### Trance (Funktionsdefinition) +### Suggestion (Funktionsdefinition) ```hyp Focus { // Funktion definieren - Trance greet(name) { + suggestion greet(name: string) { observe "Hallo, " + name + "!"; } - Trance add(a, b) { - return a + b; + suggestion add(a: number, b: number): number { + awaken a + b; } - Trance factorial(n) { + suggestion factorial(n: number): number { if (n <= 1) { - return 1; + awaken 1; } else { - return n * factorial(n - 1); + awaken n * factorial(n - 1); } } @@ -190,13 +186,13 @@ Focus { // Funktionen aufrufen greet("HypnoScript"); - induce result = add(5, 3); + induce result: number = add(5, 3); observe "5 + 3 = " + result; - induce fact = factorial(5); + induce fact: number = factorial(5); observe "5! = " + fact; } -} Relax; +} Relax ``` ### Funktionen mit Rückgabewerten @@ -255,7 +251,7 @@ Focus { observe "Array-Länge: " + length; // Array durchsuchen - for (induce i = 0; i < ArrayLength(numbers); induce i = i + 1) { + for (induce i = 0; i < Length(numbers); induce i = i + 1) { observe "Element " + i + ": " + ArrayGet(numbers, i); } } @@ -274,7 +270,7 @@ Focus { observe "Sortiert: " + sorted; // Summe - induce sum = SumArray(numbers); + induce sum = ArraySum(numbers); observe "Summe: " + sum; // Durchschnitt @@ -562,7 +558,7 @@ Focus { induce array = [1, 2, 3]; induce index = 5; - if (index >= 0 && index < ArrayLength(array)) { + if (index >= 0 && index < Length(array)) { induce value = ArrayGet(array, index); observe "Wert: " + value; } else { diff --git a/HypnoScript.Dokumentation/docs/language-reference/tranceify.md b/hypnoscript-docs/docs/language-reference/tranceify.md similarity index 100% rename from HypnoScript.Dokumentation/docs/language-reference/tranceify.md rename to hypnoscript-docs/docs/language-reference/tranceify.md diff --git a/HypnoScript.Dokumentation/docs/language-reference/variables.md b/hypnoscript-docs/docs/language-reference/variables.md similarity index 85% rename from HypnoScript.Dokumentation/docs/language-reference/variables.md rename to hypnoscript-docs/docs/language-reference/variables.md index 4cb4e2d..e763e4a 100644 --- a/HypnoScript.Dokumentation/docs/language-reference/variables.md +++ b/hypnoscript-docs/docs/language-reference/variables.md @@ -4,7 +4,11 @@ sidebar_position: 2 # Variablen und Datentypen -In HypnoScript werden Variablen mit dem Schlüsselwort `induce` deklariert. Die Sprache ist dynamisch typisiert, unterstützt aber verschiedene primitive und komplexe Datentypen. +:::tip Vollständige Referenz +Siehe [Keywords Referenz](./_keywords-reference#variablen-und-konstanten) für die vollständige Dokumentation aller Variablen-Keywords (induce, implant, freeze, anchor, oscillate). +::: + +In HypnoScript werden Variablen mit dem Schlüsselwort `induce` deklariert. Die Sprache unterstützt statisches Type Checking mit verschiedenen primitiven und komplexen Datentypen. ## Variablen deklarieren diff --git a/HypnoScript.Dokumentation/docs/reference/api.md b/hypnoscript-docs/docs/reference/api.md similarity index 100% rename from HypnoScript.Dokumentation/docs/reference/api.md rename to hypnoscript-docs/docs/reference/api.md diff --git a/HypnoScript.Dokumentation/docs/reference/compiler.md b/hypnoscript-docs/docs/reference/compiler.md similarity index 100% rename from HypnoScript.Dokumentation/docs/reference/compiler.md rename to hypnoscript-docs/docs/reference/compiler.md diff --git a/HypnoScript.Dokumentation/docs/reference/interpreter.md b/hypnoscript-docs/docs/reference/interpreter.md similarity index 97% rename from HypnoScript.Dokumentation/docs/reference/interpreter.md rename to hypnoscript-docs/docs/reference/interpreter.md index 45d3fd6..e8c086a 100644 --- a/HypnoScript.Dokumentation/docs/reference/interpreter.md +++ b/hypnoscript-docs/docs/reference/interpreter.md @@ -129,7 +129,7 @@ induce sharedSession = Session("Shared", false, true); ```hyp // Direkter Aufruf -induce result = SumArray([1,2,3]); +induce result = ArraySum([1,2,3]); // Mit Fehlerbehandlung if (IsValidEmail(email)) { @@ -215,7 +215,7 @@ for (induce i = 0; i < 1000000; induce i = i + 1) { ```hyp // Robuste Fehlerbehandlung Trance safeArrayAccess(arr, index) { - if (index < 0 || index >= ArrayLength(arr)) { + if (index < 0 || index >= Length(arr)) { return null; } return ArrayGet(arr, index); @@ -226,7 +226,7 @@ Trance safeArrayAccess(arr, index) { ```hyp // Effiziente Schleifen -induce length = ArrayLength(arr); +induce length = Length(arr); for (induce i = 0; i < length; induce i = i + 1) { // Code } diff --git a/HypnoScript.Dokumentation/docs/reference/runtime.md b/hypnoscript-docs/docs/reference/runtime.md similarity index 100% rename from HypnoScript.Dokumentation/docs/reference/runtime.md rename to hypnoscript-docs/docs/reference/runtime.md diff --git a/HypnoScript.Dokumentation/docs/testing/assertions.md b/hypnoscript-docs/docs/testing/assertions.md similarity index 100% rename from HypnoScript.Dokumentation/docs/testing/assertions.md rename to hypnoscript-docs/docs/testing/assertions.md diff --git a/hypnoscript-docs/docs/testing/best-practices.md b/hypnoscript-docs/docs/testing/best-practices.md new file mode 100644 index 0000000..8f70eab --- /dev/null +++ b/hypnoscript-docs/docs/testing/best-practices.md @@ -0,0 +1,20 @@ +# Testing Best Practices + +HypnoScript projects benefit from a layered testing strategy that mixes lightweight smoke tests with deeper integration suites. The guidance below captures the conventions used across the core repositories. + +## Combine CLI and Runtime Coverage + +- Exercise the CLI with representative `.hyp` scripts to confirm argument parsing and exit codes. +- Pair those checks with runtime-focused tests that interact with the VM APIs directly so error handling is covered even when the CLI is not involved. + +## Keep Fixtures Focused + +Store only the data each scenario needs in `docs/testing/fixtures`. Reuse shared setup utilities from the `hypnoscript-tests` package to avoid duplicating long trance sequences across files. + +## Automate Cross-Platform Runs + +Use the GitHub Actions matrix (Linux, macOS, Windows) as the source of truth. Local scripts should mirror the workflow commands to reduce surprises before merges. + +## Watch for Non-Determinism + +Disable time-sensitive or network-dependent routines unless they are required for the scenario. When randomness is essential, seed the generator through `SYSTEM::set_seed` so replays behave consistently. diff --git a/HypnoScript.Dokumentation/docs/testing/fixtures.md b/hypnoscript-docs/docs/testing/fixtures.md similarity index 96% rename from HypnoScript.Dokumentation/docs/testing/fixtures.md rename to hypnoscript-docs/docs/testing/fixtures.md index 4d76c60..d26e03a 100644 --- a/HypnoScript.Dokumentation/docs/testing/fixtures.md +++ b/hypnoscript-docs/docs/testing/fixtures.md @@ -71,7 +71,7 @@ Focus { // Test array fixtures induce numbers: number[] = numberArray; - Assert(ArrayLength(numbers) == 8, "Number array should have 8 elements"); + Assert(Length(numbers) == 8, "Number array should have 8 elements"); Assert(numbers[0] == 1, "First element should be 1"); Observe("All fixture tests passed!"); @@ -114,7 +114,7 @@ Focus { // Test dynamic fixtures Assert(dynamicUser["name"] == "Jane Smith", "Dynamic user name should match"); - Assert(ArrayLength(fibonacci) == 10, "Fibonacci array should have 10 elements"); + Assert(Length(fibonacci) == 10, "Fibonacci array should have 10 elements"); Observe("Dynamic fixture generation successful!"); } Relax @@ -157,12 +157,12 @@ Focus { return false; } - if (ArrayLength(arr) == 0) { + if (Length(arr) == 0) { return false; } // Check type consistency - for (induce i: number = 0; i < ArrayLength(arr); i = i + 1) { + for (induce i: number = 0; i < Length(arr); i = i + 1) { if (expectedType == "number" && !IsNumber(arr[i])) { return false; } @@ -413,8 +413,8 @@ Focus { // Comprehensive testing Assert(ValidateUserFixture(user), "User fixture should be valid"); - Assert(ArrayLength(products) > 0, "Products fixture should not be empty"); - Assert(ArrayLength(errors) > 0, "Error fixtures should be available"); + Assert(Length(products) > 0, "Products fixture should not be empty"); + Assert(Length(errors) > 0, "Error fixtures should be available"); Observe("Integration test with fixtures completed successfully!"); } Relax diff --git a/HypnoScript.Dokumentation/docs/testing/overview.md b/hypnoscript-docs/docs/testing/overview.md similarity index 99% rename from HypnoScript.Dokumentation/docs/testing/overview.md rename to hypnoscript-docs/docs/testing/overview.md index f9c4225..8dd851e 100644 --- a/HypnoScript.Dokumentation/docs/testing/overview.md +++ b/hypnoscript-docs/docs/testing/overview.md @@ -284,7 +284,7 @@ Benchmark "Array-Sortierung" { // Performance-Metriken speichern RecordMetric("sort_duration", duration); - RecordMetric("array_size", ArrayLength(arr)); + RecordMetric("array_size", Length(arr)); } } Relax; ``` diff --git a/HypnoScript.Dokumentation/docs/testing/performance.md b/hypnoscript-docs/docs/testing/performance.md similarity index 100% rename from HypnoScript.Dokumentation/docs/testing/performance.md rename to hypnoscript-docs/docs/testing/performance.md diff --git a/HypnoScript.Dokumentation/docs/testing/reporting.md b/hypnoscript-docs/docs/testing/reporting.md similarity index 100% rename from HypnoScript.Dokumentation/docs/testing/reporting.md rename to hypnoscript-docs/docs/testing/reporting.md diff --git a/HypnoScript.Dokumentation/docs/tutorial-basics/_category_.json b/hypnoscript-docs/docs/tutorial-basics/_category_.json similarity index 100% rename from HypnoScript.Dokumentation/docs/tutorial-basics/_category_.json rename to hypnoscript-docs/docs/tutorial-basics/_category_.json diff --git a/HypnoScript.Dokumentation/docs/tutorial-basics/congratulations.md b/hypnoscript-docs/docs/tutorial-basics/congratulations.md similarity index 100% rename from HypnoScript.Dokumentation/docs/tutorial-basics/congratulations.md rename to hypnoscript-docs/docs/tutorial-basics/congratulations.md diff --git a/HypnoScript.Dokumentation/docs/tutorial-basics/create-a-blog-post.md b/hypnoscript-docs/docs/tutorial-basics/create-a-blog-post.md similarity index 87% rename from HypnoScript.Dokumentation/docs/tutorial-basics/create-a-blog-post.md rename to hypnoscript-docs/docs/tutorial-basics/create-a-blog-post.md index 550ae17..1e10673 100644 --- a/HypnoScript.Dokumentation/docs/tutorial-basics/create-a-blog-post.md +++ b/hypnoscript-docs/docs/tutorial-basics/create-a-blog-post.md @@ -31,4 +31,4 @@ Congratulations, you have made your first post! Feel free to play around and edit this post as much as you like. ``` -A new blog post is now available at [http://localhost:3000/blog/greetings](http://localhost:3000/blog/greetings). +A new blog post is now available at `http://localhost:3000/blog/greetings`. diff --git a/HypnoScript.Dokumentation/docs/tutorial-basics/create-a-document.md b/hypnoscript-docs/docs/tutorial-basics/create-a-document.md similarity index 89% rename from HypnoScript.Dokumentation/docs/tutorial-basics/create-a-document.md rename to hypnoscript-docs/docs/tutorial-basics/create-a-document.md index c22fe29..ece4a1f 100644 --- a/HypnoScript.Dokumentation/docs/tutorial-basics/create-a-document.md +++ b/hypnoscript-docs/docs/tutorial-basics/create-a-document.md @@ -20,7 +20,7 @@ Create a Markdown file at `docs/hello.md`: This is my **first Docusaurus document**! ``` -A new document is now available at [http://localhost:3000/docs/hello](http://localhost:3000/docs/hello). +A new document is now available at `http://localhost:3000/docs/hello`. ## Configure the Sidebar diff --git a/HypnoScript.Dokumentation/docs/tutorial-basics/create-a-page.md b/hypnoscript-docs/docs/tutorial-basics/create-a-page.md similarity index 78% rename from HypnoScript.Dokumentation/docs/tutorial-basics/create-a-page.md rename to hypnoscript-docs/docs/tutorial-basics/create-a-page.md index 20e2ac3..ec4f8b3 100644 --- a/HypnoScript.Dokumentation/docs/tutorial-basics/create-a-page.md +++ b/hypnoscript-docs/docs/tutorial-basics/create-a-page.md @@ -28,7 +28,7 @@ export default function MyReactPage() { } ``` -A new page is now available at [http://localhost:3000/my-react-page](http://localhost:3000/my-react-page). +A new page is now available at `http://localhost:3000/my-react-page`. ## Create your first Markdown Page @@ -40,4 +40,4 @@ Create a file at `src/pages/my-markdown-page.md`: This is a Markdown page ``` -A new page is now available at [http://localhost:3000/my-markdown-page](http://localhost:3000/my-markdown-page). +A new page is now available at `http://localhost:3000/my-markdown-page`. diff --git a/HypnoScript.Dokumentation/docs/tutorial-basics/deploy-your-site.md b/hypnoscript-docs/docs/tutorial-basics/deploy-your-site.md similarity index 87% rename from HypnoScript.Dokumentation/docs/tutorial-basics/deploy-your-site.md rename to hypnoscript-docs/docs/tutorial-basics/deploy-your-site.md index 1c50ee0..492eae0 100644 --- a/HypnoScript.Dokumentation/docs/tutorial-basics/deploy-your-site.md +++ b/hypnoscript-docs/docs/tutorial-basics/deploy-your-site.md @@ -26,6 +26,6 @@ Test your production build locally: npm run serve ``` -The `build` folder is now served at [http://localhost:3000/](http://localhost:3000/). +The `build` folder is now served at `http://localhost:3000/`. You can now deploy the `build` folder **almost anywhere** easily, **for free** or very small cost (read the **[Deployment Guide](https://docusaurus.io/docs/deployment)**). diff --git a/HypnoScript.Dokumentation/docs/tutorial-basics/markdown-features.mdx b/hypnoscript-docs/docs/tutorial-basics/markdown-features.mdx similarity index 100% rename from HypnoScript.Dokumentation/docs/tutorial-basics/markdown-features.mdx rename to hypnoscript-docs/docs/tutorial-basics/markdown-features.mdx diff --git a/HypnoScript.Dokumentation/docs/tutorial-extras/_category_.json b/hypnoscript-docs/docs/tutorial-extras/_category_.json similarity index 100% rename from HypnoScript.Dokumentation/docs/tutorial-extras/_category_.json rename to hypnoscript-docs/docs/tutorial-extras/_category_.json diff --git a/HypnoScript.Dokumentation/docs/tutorial-extras/img/docsVersionDropdown.png b/hypnoscript-docs/docs/tutorial-extras/img/docsVersionDropdown.png similarity index 100% rename from HypnoScript.Dokumentation/docs/tutorial-extras/img/docsVersionDropdown.png rename to hypnoscript-docs/docs/tutorial-extras/img/docsVersionDropdown.png diff --git a/HypnoScript.Dokumentation/docs/tutorial-extras/img/localeDropdown.png b/hypnoscript-docs/docs/tutorial-extras/img/localeDropdown.png similarity index 100% rename from HypnoScript.Dokumentation/docs/tutorial-extras/img/localeDropdown.png rename to hypnoscript-docs/docs/tutorial-extras/img/localeDropdown.png diff --git a/HypnoScript.Dokumentation/docs/tutorial-extras/manage-docs-versions.md b/hypnoscript-docs/docs/tutorial-extras/manage-docs-versions.md similarity index 100% rename from HypnoScript.Dokumentation/docs/tutorial-extras/manage-docs-versions.md rename to hypnoscript-docs/docs/tutorial-extras/manage-docs-versions.md diff --git a/hypnoscript-docs/docs/tutorial-extras/performance.md b/hypnoscript-docs/docs/tutorial-extras/performance.md new file mode 100644 index 0000000..8b98f4c --- /dev/null +++ b/hypnoscript-docs/docs/tutorial-extras/performance.md @@ -0,0 +1,19 @@ +# Performance Tuning + +These tips help you speed up long HypnoScript sessions and reduce latency in interactive inductions. + +## Profile First + +Use `hypnoscript --profile session.hyp` to generate a flame graph that highlights expensive suggestions and loops. Focus optimization efforts on hotspots instead of guessing. + +## Avoid Excessive Context Switching + +Batch related suggestions into a single induction block. Rapidly alternating between incompatible trance states forces the runtime to rebuild safety guards and slows execution. + +## Cache External Resources + +When scripts fetch media or data from remote services, cache the results in a session-scoped dictionary. This prevents repeated requests and keeps the participant immersed. + +## Tune Garbage Collection + +Set `runtime.gc_threshold` in `hypnoscript.toml` to balance memory usage and pause times. Lower values trigger more frequent cleanup while higher values prioritize throughput. diff --git a/HypnoScript.Dokumentation/docs/tutorial-extras/translate-your-site.md b/hypnoscript-docs/docs/tutorial-extras/translate-your-site.md similarity index 91% rename from HypnoScript.Dokumentation/docs/tutorial-extras/translate-your-site.md rename to hypnoscript-docs/docs/tutorial-extras/translate-your-site.md index b5a644a..c41f744 100644 --- a/HypnoScript.Dokumentation/docs/tutorial-extras/translate-your-site.md +++ b/hypnoscript-docs/docs/tutorial-extras/translate-your-site.md @@ -39,7 +39,7 @@ Start your site on the French locale: npm run start -- --locale fr ``` -Your localized site is accessible at [http://localhost:3000/fr/](http://localhost:3000/fr/) and the `Getting Started` page is translated. +Your localized site is accessible at `http://localhost:3000/fr/` and the `Getting Started` page is translated. :::caution diff --git a/hypnoscript-docs/package-lock.json b/hypnoscript-docs/package-lock.json new file mode 100644 index 0000000..cf56155 --- /dev/null +++ b/hypnoscript-docs/package-lock.json @@ -0,0 +1,2604 @@ +{ + "name": "hypnoscript-documentation", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "hypnoscript-documentation", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "vue": "^3.4.21" + }, + "devDependencies": { + "typescript": "^5.3.3", + "vitepress": "^1.5.0" + }, + "engines": { + "node": ">=18.0" + } + }, + "node_modules/@algolia/client-abtesting": { + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.29.0.tgz", + "integrity": "sha512-AM/6LYMSTnZvAT5IarLEKjYWOdV+Fb+LVs8JRq88jn8HH6bpVUtjWdOZXqX1hJRXuCAY8SdQfb7F8uEiMNXdYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.29.0", + "@algolia/requester-browser-xhr": "5.29.0", + "@algolia/requester-fetch": "5.29.0", + "@algolia/requester-node-http": "5.29.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-analytics": { + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.29.0.tgz", + "integrity": "sha512-La34HJh90l0waw3wl5zETO8TuukeUyjcXhmjYZL3CAPLggmKv74mobiGRIb+mmBENybiFDXf/BeKFLhuDYWMMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.29.0", + "@algolia/requester-browser-xhr": "5.29.0", + "@algolia/requester-fetch": "5.29.0", + "@algolia/requester-node-http": "5.29.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-common": { + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.29.0.tgz", + "integrity": "sha512-T0lzJH/JiCxQYtCcnWy7Jf1w/qjGDXTi2npyF9B9UsTvXB97GRC6icyfXxe21mhYvhQcaB1EQ/J2575FXxi2rA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-insights": { + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.29.0.tgz", + "integrity": "sha512-A39F1zmHY9aev0z4Rt3fTLcGN5AG1VsVUkVWy6yQG5BRDScktH+U5m3zXwThwniBTDV1HrPgiGHZeWb67GkR2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.29.0", + "@algolia/requester-browser-xhr": "5.29.0", + "@algolia/requester-fetch": "5.29.0", + "@algolia/requester-node-http": "5.29.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-personalization": { + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.29.0.tgz", + "integrity": "sha512-ibxmh2wKKrzu5du02gp8CLpRMeo+b/75e4ORct98CT7mIxuYFXowULwCd6cMMkz/R0LpKXIbTUl15UL5soaiUQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.29.0", + "@algolia/requester-browser-xhr": "5.29.0", + "@algolia/requester-fetch": "5.29.0", + "@algolia/requester-node-http": "5.29.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-query-suggestions": { + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.29.0.tgz", + "integrity": "sha512-VZq4/AukOoJC2WSwF6J5sBtt+kImOoBwQc1nH3tgI+cxJBg7B77UsNC+jT6eP2dQCwGKBBRTmtPLUTDDnHpMgA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.29.0", + "@algolia/requester-browser-xhr": "5.29.0", + "@algolia/requester-fetch": "5.29.0", + "@algolia/requester-node-http": "5.29.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-search": { + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.29.0.tgz", + "integrity": "sha512-cZ0Iq3OzFUPpgszzDr1G1aJV5UMIZ4VygJ2Az252q4Rdf5cQMhYEIKArWY/oUjMhQmosM8ygOovNq7gvA9CdCg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@algolia/client-common": "5.29.0", + "@algolia/requester-browser-xhr": "5.29.0", + "@algolia/requester-fetch": "5.29.0", + "@algolia/requester-node-http": "5.29.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/ingestion": { + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.29.0.tgz", + "integrity": "sha512-scBXn0wO5tZCxmO6evfa7A3bGryfyOI3aoXqSQBj5SRvNYXaUlFWQ/iKI70gRe/82ICwE0ICXbHT/wIvxOW7vw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.29.0", + "@algolia/requester-browser-xhr": "5.29.0", + "@algolia/requester-fetch": "5.29.0", + "@algolia/requester-node-http": "5.29.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/monitoring": { + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.29.0.tgz", + "integrity": "sha512-FGWWG9jLFhsKB7YiDjM2dwQOYnWu//7Oxrb2vT96N7+s+hg1mdHHfHNRyEudWdxd4jkMhBjeqNA21VbTiOIPVg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.29.0", + "@algolia/requester-browser-xhr": "5.29.0", + "@algolia/requester-fetch": "5.29.0", + "@algolia/requester-node-http": "5.29.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/recommend": { + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.29.0.tgz", + "integrity": "sha512-xte5+mpdfEARAu61KXa4ewpjchoZuJlAlvQb8ptK6hgHlBHDnYooy1bmOFpokaAICrq/H9HpoqNUX71n+3249A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.29.0", + "@algolia/requester-browser-xhr": "5.29.0", + "@algolia/requester-fetch": "5.29.0", + "@algolia/requester-node-http": "5.29.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/requester-browser-xhr": { + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.29.0.tgz", + "integrity": "sha512-og+7Em75aPHhahEUScq2HQ3J7ULN63Levtd87BYMpn6Im5d5cNhaC4QAUsXu6LWqxRPgh4G+i+wIb6tVhDhg2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.29.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/requester-fetch": { + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.29.0.tgz", + "integrity": "sha512-JCxapz7neAy8hT/nQpCvOrI5JO8VyQ1kPvBiaXWNC1prVq0UMYHEL52o1BsPvtXfdQ7BVq19OIq6TjOI06mV/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.29.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/requester-node-http": { + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.29.0.tgz", + "integrity": "sha512-lVBD81RBW5VTdEYgnzCz7Pf9j2H44aymCP+/eHGJu4vhU+1O8aKf3TVBgbQr5UM6xoe8IkR/B112XY6YIG2vtg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.29.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", + "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.5" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", + "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@docsearch/js": { + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/@docsearch/js/-/js-3.8.2.tgz", + "integrity": "sha512-Q5wY66qHn0SwA7Taa0aDbHiJvaFJLOJyHmooQ7y8hlwwQLQ/5WwCcoX0g7ii04Qi2DJlHsd0XXzJ8Ypw9+9YmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@docsearch/react": "3.8.2", + "preact": "^10.0.0" + } + }, + "node_modules/@docsearch/js/node_modules/@algolia/autocomplete-core": { + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.17.7.tgz", + "integrity": "sha512-BjiPOW6ks90UKl7TwMv7oNQMnzU+t/wk9mgIDi6b1tXpUek7MW0lbNOUHpvam9pe3lVCf4xPFT+lK7s+e+fs7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/autocomplete-plugin-algolia-insights": "1.17.7", + "@algolia/autocomplete-shared": "1.17.7" + } + }, + "node_modules/@docsearch/js/node_modules/@algolia/autocomplete-plugin-algolia-insights": { + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.17.7.tgz", + "integrity": "sha512-Jca5Ude6yUOuyzjnz57og7Et3aXjbwCSDf/8onLHSQgw1qW3ALl9mrMWaXb5FmPVkV3EtkD2F/+NkT6VHyPu9A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/autocomplete-shared": "1.17.7" + }, + "peerDependencies": { + "search-insights": ">= 1 < 3" + } + }, + "node_modules/@docsearch/js/node_modules/@algolia/autocomplete-preset-algolia": { + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.17.7.tgz", + "integrity": "sha512-ggOQ950+nwbWROq2MOCIL71RE0DdQZsceqrg32UqnhDz8FlO9rL8ONHNsI2R1MH0tkgVIDKI/D0sMiUchsFdWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/autocomplete-shared": "1.17.7" + }, + "peerDependencies": { + "@algolia/client-search": ">= 4.9.1 < 6", + "algoliasearch": ">= 4.9.1 < 6" + } + }, + "node_modules/@docsearch/js/node_modules/@algolia/autocomplete-shared": { + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.17.7.tgz", + "integrity": "sha512-o/1Vurr42U/qskRSuhBH+VKxMvkkUVTLU6WZQr+L5lGZZLYWyhdzWjW0iGXY7EkwRTjBqvN2EsR81yCTGV/kmg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@algolia/client-search": ">= 4.9.1 < 6", + "algoliasearch": ">= 4.9.1 < 6" + } + }, + "node_modules/@docsearch/js/node_modules/@docsearch/css": { + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.8.2.tgz", + "integrity": "sha512-y05ayQFyUmCXze79+56v/4HpycYF3uFqB78pLPrSV5ZKAlDuIAAJNhaRi8tTdRNXh05yxX/TyNnzD6LwSM89vQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@docsearch/js/node_modules/@docsearch/react": { + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.8.2.tgz", + "integrity": "sha512-xCRrJQlTt8N9GU0DG4ptwHRkfnSnD/YpdeaXe02iKfqs97TkZJv60yE+1eq/tjPcVnTW8dP5qLP7itifFVV5eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/autocomplete-core": "1.17.7", + "@algolia/autocomplete-preset-algolia": "1.17.7", + "@docsearch/css": "3.8.2", + "algoliasearch": "^5.14.2" + }, + "peerDependencies": { + "@types/react": ">= 16.8.0 < 19.0.0", + "react": ">= 16.8.0 < 19.0.0", + "react-dom": ">= 16.8.0 < 19.0.0", + "search-insights": ">= 1 < 3" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "search-insights": { + "optional": true + } + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@iconify-json/simple-icons": { + "version": "1.2.58", + "resolved": "https://registry.npmjs.org/@iconify-json/simple-icons/-/simple-icons-1.2.58.tgz", + "integrity": "sha512-XtXEoRALqztdNc9ujYBj2tTCPKdIPKJBdLNDebFF46VV1aOAwTbAYMgNsK5GMCpTJupLCmpBWDn+gX5SpECorQ==", + "dev": true, + "license": "CC0-1.0", + "dependencies": { + "@iconify/types": "*" + } + }, + "node_modules/@iconify/types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz", + "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "dev": true, + "license": "MIT", + "optional": 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, + "license": "MIT", + "optional": 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, + "license": "MIT", + "optional": 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, + "license": "MIT", + "optional": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "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, + "license": "MIT", + "optional": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.2.tgz", + "integrity": "sha512-yDPzwsgiFO26RJA4nZo8I+xqzh7sJTZIWQOxn+/XOdPE31lAvLIYCKqjV+lNH/vxE2L2iH3plKxDCRK6i+CwhA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.2.tgz", + "integrity": "sha512-k8FontTxIE7b0/OGKeSN5B6j25EuppBcWM33Z19JoVT7UTXFSo3D9CdU39wGTeb29NO3XxpMNauh09B+Ibw+9g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.2.tgz", + "integrity": "sha512-A6s4gJpomNBtJ2yioj8bflM2oogDwzUiMl2yNJ2v9E7++sHrSrsQ29fOfn5DM/iCzpWcebNYEdXpaK4tr2RhfQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.2.tgz", + "integrity": "sha512-e6XqVmXlHrBlG56obu9gDRPW3O3hLxpwHpLsBJvuI8qqnsrtSZ9ERoWUXtPOkY8c78WghyPHZdmPhHLWNdAGEw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.2.tgz", + "integrity": "sha512-v0E9lJW8VsrwPux5Qe5CwmH/CF/2mQs6xU1MF3nmUxmZUCHazCjLgYvToOk+YuuUqLQBio1qkkREhxhc656ViA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.2.tgz", + "integrity": "sha512-ClAmAPx3ZCHtp6ysl4XEhWU69GUB1D+s7G9YjHGhIGCSrsg00nEGRRZHmINYxkdoJehde8VIsDC5t9C0gb6yqA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.2.tgz", + "integrity": "sha512-EPlb95nUsz6Dd9Qy13fI5kUPXNSljaG9FiJ4YUGU1O/Q77i5DYFW5KR8g1OzTcdZUqQQ1KdDqsTohdFVwCwjqg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.2.tgz", + "integrity": "sha512-BOmnVW+khAUX+YZvNfa0tGTEMVVEerOxN0pDk2E6N6DsEIa2Ctj48FOMfNDdrwinocKaC7YXUZ1pHlKpnkja/Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.2.tgz", + "integrity": "sha512-Xt2byDZ+6OVNuREgBXr4+CZDJtrVso5woFtpKdGPhpTPHcNG7D8YXeQzpNbFRxzTVqJf7kvPMCub/pcGUWgBjA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.2.tgz", + "integrity": "sha512-+LdZSldy/I9N8+klim/Y1HsKbJ3BbInHav5qE9Iy77dtHC/pibw1SR/fXlWyAk0ThnpRKoODwnAuSjqxFRDHUQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.2.tgz", + "integrity": "sha512-8ms8sjmyc1jWJS6WdNSA23rEfdjWB30LH8Wqj0Cqvv7qSHnvw6kgMMXRdop6hkmGPlyYBdRPkjJnj3KCUHV/uQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.2.tgz", + "integrity": "sha512-3HRQLUQbpBDMmzoxPJYd3W6vrVHOo2cVW8RUo87Xz0JPJcBLBr5kZ1pGcQAhdZgX9VV7NbGNipah1omKKe23/g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.2.tgz", + "integrity": "sha512-fMjKi+ojnmIvhk34gZP94vjogXNNUKMEYs+EDaB/5TG/wUkoeua7p7VCHnE6T2Tx+iaghAqQX8teQzcvrYpaQA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.2.tgz", + "integrity": "sha512-XuGFGU+VwUUV5kLvoAdi0Wz5Xbh2SrjIxCtZj6Wq8MDp4bflb/+ThZsVxokM7n0pcbkEr2h5/pzqzDYI7cCgLQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.2.tgz", + "integrity": "sha512-w6yjZF0P+NGzWR3AXWX9zc0DNEGdtvykB03uhonSHMRa+oWA6novflo2WaJr6JZakG2ucsyb+rvhrKac6NIy+w==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.2.tgz", + "integrity": "sha512-yo8d6tdfdeBArzC7T/PnHd7OypfI9cbuZzPnzLJIyKYFhAQ8SvlkKtKBMbXDxe1h03Rcr7u++nFS7tqXz87Gtw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.2.tgz", + "integrity": "sha512-ah59c1YkCxKExPP8O9PwOvs+XRLKwh/mV+3YdKqQ5AMQ0r4M4ZDuOrpWkUaqO7fzAHdINzV9tEVu8vNw48z0lA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.2.tgz", + "integrity": "sha512-4VEd19Wmhr+Zy7hbUsFZ6YXEiP48hE//KPLCSVNY5RMGX2/7HZ+QkN55a3atM1C/BZCGIgqN+xrVgtdak2S9+A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.2.tgz", + "integrity": "sha512-IlbHFYc/pQCgew/d5fslcy1KEaYVCJ44G8pajugd8VoOEI8ODhtb/j8XMhLpwHCMB3yk2J07ctup10gpw2nyMA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.2.tgz", + "integrity": "sha512-lNlPEGgdUfSzdCWU176ku/dQRnA7W+Gp8d+cWv73jYrb8uT7HTVVxq62DUYxjbaByuf1Yk0RIIAbDzp+CnOTFg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.2.tgz", + "integrity": "sha512-S6YojNVrHybQis2lYov1sd+uj7K0Q05NxHcGktuMMdIQ2VixGwAfbJ23NnlvvVV1bdpR2m5MsNBViHJKcA4ADw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.2.tgz", + "integrity": "sha512-k+/Rkcyx//P6fetPoLMb8pBeqJBNGx81uuf7iljX9++yNBVRDQgD04L+SVXmXmh5ZP4/WOp4mWF0kmi06PW2tA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@shikijs/core": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-2.5.0.tgz", + "integrity": "sha512-uu/8RExTKtavlpH7XqnVYBrfBkUc20ngXiX9NSrBhOVZYv/7XQRKUyhtkeflY5QsxC0GbJThCerruZfsUaSldg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/engine-javascript": "2.5.0", + "@shikijs/engine-oniguruma": "2.5.0", + "@shikijs/types": "2.5.0", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4", + "hast-util-to-html": "^9.0.4" + } + }, + "node_modules/@shikijs/engine-javascript": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-2.5.0.tgz", + "integrity": "sha512-VjnOpnQf8WuCEZtNUdjjwGUbtAVKuZkVQ/5cHy/tojVVRIRtlWMYVjyWhxOmIq05AlSOv72z7hRNRGVBgQOl0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "2.5.0", + "@shikijs/vscode-textmate": "^10.0.2", + "oniguruma-to-es": "^3.1.0" + } + }, + "node_modules/@shikijs/engine-oniguruma": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-2.5.0.tgz", + "integrity": "sha512-pGd1wRATzbo/uatrCIILlAdFVKdxImWJGQ5rFiB5VZi2ve5xj3Ax9jny8QvkaV93btQEwR/rSz5ERFpC5mKNIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "2.5.0", + "@shikijs/vscode-textmate": "^10.0.2" + } + }, + "node_modules/@shikijs/langs": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-2.5.0.tgz", + "integrity": "sha512-Qfrrt5OsNH5R+5tJ/3uYBBZv3SuGmnRPejV9IlIbFH3HTGLDlkqgHymAlzklVmKBjAaVmkPkyikAV/sQ1wSL+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "2.5.0" + } + }, + "node_modules/@shikijs/themes": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-2.5.0.tgz", + "integrity": "sha512-wGrk+R8tJnO0VMzmUExHR+QdSaPUl/NKs+a4cQQRWyoc3YFbUzuLEi/KWK1hj+8BfHRKm2jNhhJck1dfstJpiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "2.5.0" + } + }, + "node_modules/@shikijs/transformers": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@shikijs/transformers/-/transformers-2.5.0.tgz", + "integrity": "sha512-SI494W5X60CaUwgi8u4q4m4s3YAFSxln3tzNjOSYqq54wlVgz0/NbbXEb3mdLbqMBztcmS7bVTaEd2w0qMmfeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/core": "2.5.0", + "@shikijs/types": "2.5.0" + } + }, + "node_modules/@shikijs/types": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-2.5.0.tgz", + "integrity": "sha512-ygl5yhxki9ZLNuNpPitBWvcy9fsSKKaRuO4BAlMyagszQidxcpLAr0qiW/q43DtSIDxO6hEbtYLiFZNXO/hdGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + } + }, + "node_modules/@shikijs/vscode-textmate": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", + "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "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": "*" + } + }, + "node_modules/@types/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/markdown-it": { + "version": "14.1.2", + "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz", + "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/linkify-it": "^5", + "@types/mdurl": "^2" + } + }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/unist": { + "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" + }, + "node_modules/@types/web-bluetooth": { + "version": "0.0.21", + "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.21.tgz", + "integrity": "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "dev": true, + "license": "ISC" + }, + "node_modules/@vitejs/plugin-vue": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.2.4.tgz", + "integrity": "sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "vite": "^5.0.0 || ^6.0.0", + "vue": "^3.2.25" + } + }, + "node_modules/@vue/compiler-core": { + "version": "3.5.24", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.24.tgz", + "integrity": "sha512-eDl5H57AOpNakGNAkFDH+y7kTqrQpJkZFXhWZQGyx/5Wh7B1uQYvcWkvZi11BDhscPgj8N7XV3oRwiPnx1Vrig==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "@vue/shared": "3.5.24", + "entities": "^4.5.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-core/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "license": "MIT" + }, + "node_modules/@vue/compiler-dom": { + "version": "3.5.24", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.24.tgz", + "integrity": "sha512-1QHGAvs53gXkWdd3ZMGYuvQFXHW4ksKWPG8HP8/2BscrbZ0brw183q2oNWjMrSWImYLHxHrx1ItBQr50I/q2zw==", + "license": "MIT", + "dependencies": { + "@vue/compiler-core": "3.5.24", + "@vue/shared": "3.5.24" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.5.24", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.24.tgz", + "integrity": "sha512-8EG5YPRgmTB+YxYBM3VXy8zHD9SWHUJLIGPhDovo3Z8VOgvP+O7UP5vl0J4BBPWYD9vxtBabzW1EuEZ+Cqs14g==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "@vue/compiler-core": "3.5.24", + "@vue/compiler-dom": "3.5.24", + "@vue/compiler-ssr": "3.5.24", + "@vue/shared": "3.5.24", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.21", + "postcss": "^8.5.6", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-sfc/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "license": "MIT" + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.5.24", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.24.tgz", + "integrity": "sha512-trOvMWNBMQ/odMRHW7Ae1CdfYx+7MuiQu62Jtu36gMLXcaoqKvAyh+P73sYG9ll+6jLB6QPovqoKGGZROzkFFg==", + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.24", + "@vue/shared": "3.5.24" + } + }, + "node_modules/@vue/devtools-api": { + "version": "7.7.8", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.7.8.tgz", + "integrity": "sha512-BtFcAmDbtXGwurWUFf8ogIbgZyR+rcVES1TSNEI8Em80fD8Anu+qTRN1Fc3J6vdRHlVM3fzPV1qIo+B4AiqGzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/devtools-kit": "^7.7.8" + } + }, + "node_modules/@vue/devtools-kit": { + "version": "7.7.8", + "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.7.8.tgz", + "integrity": "sha512-4Y8op+AoxOJhB9fpcEF6d5vcJXWKgHxC3B0ytUB8zz15KbP9g9WgVzral05xluxi2fOeAy6t140rdQ943GcLRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/devtools-shared": "^7.7.8", + "birpc": "^2.3.0", + "hookable": "^5.5.3", + "mitt": "^3.0.1", + "perfect-debounce": "^1.0.0", + "speakingurl": "^14.0.1", + "superjson": "^2.2.2" + } + }, + "node_modules/@vue/devtools-shared": { + "version": "7.7.8", + "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.7.8.tgz", + "integrity": "sha512-XHpO3jC5nOgYr40M9p8Z4mmKfTvUxKyRcUnpBAYg11pE78eaRFBKb0kG5yKLroMuJeeNH9LWmKp2zMU5LUc7CA==", + "dev": true, + "license": "MIT", + "dependencies": { + "rfdc": "^1.4.1" + } + }, + "node_modules/@vue/reactivity": { + "version": "3.5.24", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.24.tgz", + "integrity": "sha512-BM8kBhtlkkbnyl4q+HiF5R5BL0ycDPfihowulm02q3WYp2vxgPcJuZO866qa/0u3idbMntKEtVNuAUp5bw4teg==", + "license": "MIT", + "dependencies": { + "@vue/shared": "3.5.24" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.5.24", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.24.tgz", + "integrity": "sha512-RYP/byyKDgNIqfX/gNb2PB55dJmM97jc9wyF3jK7QUInYKypK2exmZMNwnjueWwGceEkP6NChd3D2ZVEp9undQ==", + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.24", + "@vue/shared": "3.5.24" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.5.24", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.24.tgz", + "integrity": "sha512-Z8ANhr/i0XIluonHVjbUkjvn+CyrxbXRIxR7wn7+X7xlcb7dJsfITZbkVOeJZdP8VZwfrWRsWdShH6pngMxRjw==", + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.24", + "@vue/runtime-core": "3.5.24", + "@vue/shared": "3.5.24", + "csstype": "^3.1.3" + } + }, + "node_modules/@vue/server-renderer": { + "version": "3.5.24", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.24.tgz", + "integrity": "sha512-Yh2j2Y4G/0/4z/xJ1Bad4mxaAk++C2v4kaa8oSYTMJBJ00/ndPuxCnWeot0/7/qafQFLh5pr6xeV6SdMcE/G1w==", + "license": "MIT", + "dependencies": { + "@vue/compiler-ssr": "3.5.24", + "@vue/shared": "3.5.24" + }, + "peerDependencies": { + "vue": "3.5.24" + } + }, + "node_modules/@vue/shared": { + "version": "3.5.24", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.24.tgz", + "integrity": "sha512-9cwHL2EsJBdi8NY22pngYYWzkTDhld6fAD6jlaeloNGciNSJL6bLpbxVgXl96X00Jtc6YWQv96YA/0sxex/k1A==", + "license": "MIT" + }, + "node_modules/@vueuse/core": { + "version": "12.8.2", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-12.8.2.tgz", + "integrity": "sha512-HbvCmZdzAu3VGi/pWYm5Ut+Kd9mn1ZHnn4L5G8kOQTPs/IwIAmJoBrmYk2ckLArgMXZj0AW3n5CAejLUO+PhdQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/web-bluetooth": "^0.0.21", + "@vueuse/metadata": "12.8.2", + "@vueuse/shared": "12.8.2", + "vue": "^3.5.13" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/integrations": { + "version": "12.8.2", + "resolved": "https://registry.npmjs.org/@vueuse/integrations/-/integrations-12.8.2.tgz", + "integrity": "sha512-fbGYivgK5uBTRt7p5F3zy6VrETlV9RtZjBqd1/HxGdjdckBgBM4ugP8LHpjolqTj14TXTxSK1ZfgPbHYyGuH7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vueuse/core": "12.8.2", + "@vueuse/shared": "12.8.2", + "vue": "^3.5.13" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "async-validator": "^4", + "axios": "^1", + "change-case": "^5", + "drauu": "^0.4", + "focus-trap": "^7", + "fuse.js": "^7", + "idb-keyval": "^6", + "jwt-decode": "^4", + "nprogress": "^0.2", + "qrcode": "^1.5", + "sortablejs": "^1", + "universal-cookie": "^7" + }, + "peerDependenciesMeta": { + "async-validator": { + "optional": true + }, + "axios": { + "optional": true + }, + "change-case": { + "optional": true + }, + "drauu": { + "optional": true + }, + "focus-trap": { + "optional": true + }, + "fuse.js": { + "optional": true + }, + "idb-keyval": { + "optional": true + }, + "jwt-decode": { + "optional": true + }, + "nprogress": { + "optional": true + }, + "qrcode": { + "optional": true + }, + "sortablejs": { + "optional": true + }, + "universal-cookie": { + "optional": true + } + } + }, + "node_modules/@vueuse/metadata": { + "version": "12.8.2", + "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-12.8.2.tgz", + "integrity": "sha512-rAyLGEuoBJ/Il5AmFHiziCPdQzRt88VxR+Y/A/QhJ1EWtWqPBBAxTAFaSkviwEuOEZNtW8pvkPgoCZQ+HxqW1A==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/shared": { + "version": "12.8.2", + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-12.8.2.tgz", + "integrity": "sha512-dznP38YzxZoNloI0qpEfpkms8knDtaoQ6Y/sfS0L7Yki4zh40LFHEhur0odJC6xTHG5dxWVPiUWBXn+wCG2s5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "vue": "^3.5.13" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "optional": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/algoliasearch": { + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.29.0.tgz", + "integrity": "sha512-E2l6AlTWGznM2e7vEE6T6hzObvEyXukxMOlBmVlMyixZyK1umuO/CiVc6sDBbzVH0oEviCE5IfVY1oZBmccYPQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@algolia/client-abtesting": "5.29.0", + "@algolia/client-analytics": "5.29.0", + "@algolia/client-common": "5.29.0", + "@algolia/client-insights": "5.29.0", + "@algolia/client-personalization": "5.29.0", + "@algolia/client-query-suggestions": "5.29.0", + "@algolia/client-search": "5.29.0", + "@algolia/ingestion": "1.29.0", + "@algolia/monitoring": "1.29.0", + "@algolia/recommend": "5.29.0", + "@algolia/requester-browser-xhr": "5.29.0", + "@algolia/requester-fetch": "5.29.0", + "@algolia/requester-node-http": "5.29.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/birpc": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/birpc/-/birpc-2.8.0.tgz", + "integrity": "sha512-Bz2a4qD/5GRhiHSwj30c/8kC8QGj12nNDwz3D4ErQ4Xhy35dsSDvF+RA/tWpjyU0pdGtSDiEk6B5fBGE1qNVhw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "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, + "license": "MIT", + "optional": true + }, + "node_modules/ccount": { + "version": "2.0.1", + "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" + } + }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "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" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "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" + } + }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "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" + } + }, + "node_modules/copy-anything": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-4.0.5.tgz", + "integrity": "sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-what": "^5.2.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/devlop": { + "version": "1.1.0", + "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" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "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, + "license": "MIT" + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/focus-trap": { + "version": "7.6.6", + "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.6.6.tgz", + "integrity": "sha512-v/Z8bvMCajtx4mEXmOo7QEsIzlIOqRXTIwgUfsFOF9gEsespdbD0AkPIka1bSXZ8Y8oZ+2IVDQZePkTfEHZl7Q==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "tabbable": "^6.3.0" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/hast-util-to-html": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz", + "integrity": "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-whitespace": "^3.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "stringify-entities": "^4.0.0", + "zwitch": "^2.0.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "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" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hookable": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz", + "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==", + "dev": true, + "license": "MIT" + }, + "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" + } + }, + "node_modules/is-what": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-5.5.0.tgz", + "integrity": "sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/mark.js": { + "version": "8.11.1", + "resolved": "https://registry.npmjs.org/mark.js/-/mark.js-8.11.1.tgz", + "integrity": "sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.0", + "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", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-util-encode": { + "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": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-sanitize-uri": { + "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": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri/node_modules/micromark-util-character": { + "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": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri/node_modules/micromark-util-symbol": { + "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": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/minisearch": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/minisearch/-/minisearch-7.2.0.tgz", + "integrity": "sha512-dqT2XBYUOZOiC5t2HRnwADjhNS2cecp9u+TJRiJ1Qp/f5qjkeT5APcGPjHw+bz89Ms8Jp+cG4AlE+QZ/QnDglg==", + "dev": true, + "license": "MIT" + }, + "node_modules/mitt": { + "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" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/oniguruma-to-es": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-3.1.1.tgz", + "integrity": "sha512-bUH8SDvPkH3ho3dvwJwfonjlQ4R80vjyvrU8YpxuROddv55vAEJrTuCuCVUhhsHbtlD9tGGbaNApGQckXhS8iQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex-xs": "^1.0.0", + "regex": "^6.0.1", + "regex-recursion": "^6.0.2" + } + }, + "node_modules/perfect-debounce": { + "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" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/preact": { + "version": "10.27.2", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.27.2.tgz", + "integrity": "sha512-5SYSgFKSyhCbk6SrXyMpqjb5+MQBgfvEKE/OC+PujcY34sOpqtr+0AZQtPYx5IA6VxynQ7rUPCtKzyovpj9Bpg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + }, + "node_modules/property-information": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", + "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/regex/-/regex-6.0.1.tgz", + "integrity": "sha512-uorlqlzAKjKQZ5P+kTJr3eeJGSVroLKoHmquUj4zHWuR+hEyNqlXsSKlYYF5F4NI6nl7tWCs0apKJ0lmfsXAPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "regex-utilities": "^2.3.0" + } + }, + "node_modules/regex-recursion": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/regex-recursion/-/regex-recursion-6.0.2.tgz", + "integrity": "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==", + "dev": true, + "license": "MIT", + "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, + "license": "MIT" + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true, + "license": "MIT" + }, + "node_modules/rollup": { + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.2.tgz", + "integrity": "sha512-MHngMYwGJVi6Fmnk6ISmnk7JAHRNF0UkuucA0CUW3N3a4KnONPEZz+vUanQP/ZC/iY1Qkf3bwPWzyY84wEks1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.53.2", + "@rollup/rollup-android-arm64": "4.53.2", + "@rollup/rollup-darwin-arm64": "4.53.2", + "@rollup/rollup-darwin-x64": "4.53.2", + "@rollup/rollup-freebsd-arm64": "4.53.2", + "@rollup/rollup-freebsd-x64": "4.53.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.53.2", + "@rollup/rollup-linux-arm-musleabihf": "4.53.2", + "@rollup/rollup-linux-arm64-gnu": "4.53.2", + "@rollup/rollup-linux-arm64-musl": "4.53.2", + "@rollup/rollup-linux-loong64-gnu": "4.53.2", + "@rollup/rollup-linux-ppc64-gnu": "4.53.2", + "@rollup/rollup-linux-riscv64-gnu": "4.53.2", + "@rollup/rollup-linux-riscv64-musl": "4.53.2", + "@rollup/rollup-linux-s390x-gnu": "4.53.2", + "@rollup/rollup-linux-x64-gnu": "4.53.2", + "@rollup/rollup-linux-x64-musl": "4.53.2", + "@rollup/rollup-openharmony-arm64": "4.53.2", + "@rollup/rollup-win32-arm64-msvc": "4.53.2", + "@rollup/rollup-win32-ia32-msvc": "4.53.2", + "@rollup/rollup-win32-x64-gnu": "4.53.2", + "@rollup/rollup-win32-x64-msvc": "4.53.2", + "fsevents": "~2.3.2" + } + }, + "node_modules/search-insights": { + "version": "2.17.3", + "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.17.3.tgz", + "integrity": "sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/shiki": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-2.5.0.tgz", + "integrity": "sha512-mI//trrsaiCIPsja5CNfsyNOqgAZUb6VpJA+340toL42UpzQlXpwRV9nch69X6gaUxrr9kaOOa6e3y3uAkGFxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/core": "2.5.0", + "@shikijs/engine-javascript": "2.5.0", + "@shikijs/engine-oniguruma": "2.5.0", + "@shikijs/langs": "2.5.0", + "@shikijs/themes": "2.5.0", + "@shikijs/types": "2.5.0", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + } + }, + "node_modules/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==", + "license": "BSD-3-Clause", + "engines": { + "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, + "license": "MIT", + "optional": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/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, + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.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" + } + }, + "node_modules/speakingurl": { + "version": "14.0.1", + "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" + } + }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "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" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/superjson": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.5.tgz", + "integrity": "sha512-zWPTX96LVsA/eVYnqOM2+ofcdPqdS1dAF1LN4TS2/MWuUpfitd9ctTa87wt4xrYnZnkLtS69xpBdSxVBP5Rm6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "copy-anything": "^4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/tabbable": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.3.0.tgz", + "integrity": "sha512-EIHvdY5bPLuWForiR/AN2Bxngzpuwn1is4asboytXtpTgsArc+WmSJKVLlhdh71u7jFcryDqB2A8lQvj78MkyQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/terser": { + "version": "5.43.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.43.1.tgz", + "integrity": "sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.14.0", + "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, + "license": "MIT", + "optional": true + }, + "node_modules/trim-lines": { + "version": "3.0.1", + "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" + } + }, + "node_modules/typescript": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "devOptional": true, + "license": "Apache-2.0", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.0", + "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" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "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" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "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" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.0.0", + "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", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "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" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile": { + "version": "6.0.3", + "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" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.2", + "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" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vite": { + "version": "5.4.21", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz", + "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.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", + "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 + } + } + }, + "node_modules/vitepress": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/vitepress/-/vitepress-1.6.4.tgz", + "integrity": "sha512-+2ym1/+0VVrbhNyRoFFesVvBvHAVMZMK0rw60E3X/5349M1GuVdKeazuksqopEdvkKwKGs21Q729jX81/bkBJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@docsearch/css": "3.8.2", + "@docsearch/js": "3.8.2", + "@iconify-json/simple-icons": "^1.2.21", + "@shikijs/core": "^2.1.0", + "@shikijs/transformers": "^2.1.0", + "@shikijs/types": "^2.1.0", + "@types/markdown-it": "^14.1.2", + "@vitejs/plugin-vue": "^5.2.1", + "@vue/devtools-api": "^7.7.0", + "@vue/shared": "^3.5.13", + "@vueuse/core": "^12.4.0", + "@vueuse/integrations": "^12.4.0", + "focus-trap": "^7.6.4", + "mark.js": "8.11.1", + "minisearch": "^7.1.1", + "shiki": "^2.1.0", + "vite": "^5.4.14", + "vue": "^3.5.13" + }, + "bin": { + "vitepress": "bin/vitepress.js" + }, + "peerDependencies": { + "markdown-it-mathjax3": "^4", + "postcss": "^8" + }, + "peerDependenciesMeta": { + "markdown-it-mathjax3": { + "optional": true + }, + "postcss": { + "optional": true + } + } + }, + "node_modules/vitepress/node_modules/@docsearch/css": { + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.8.2.tgz", + "integrity": "sha512-y05ayQFyUmCXze79+56v/4HpycYF3uFqB78pLPrSV5ZKAlDuIAAJNhaRi8tTdRNXh05yxX/TyNnzD6LwSM89vQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/vue": { + "version": "3.5.24", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.24.tgz", + "integrity": "sha512-uTHDOpVQTMjcGgrqFPSb8iO2m1DUvo+WbGqoXQz8Y1CeBYQ0FXf2z1gLRaBtHjlRz7zZUBHxjVB5VTLzYkvftg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@vue/compiler-dom": "3.5.24", + "@vue/compiler-sfc": "3.5.24", + "@vue/runtime-dom": "3.5.24", + "@vue/server-renderer": "3.5.24", + "@vue/shared": "3.5.24" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + } + } +} diff --git a/hypnoscript-docs/package.json b/hypnoscript-docs/package.json new file mode 100644 index 0000000..c19735a --- /dev/null +++ b/hypnoscript-docs/package.json @@ -0,0 +1,39 @@ +{ + "name": "hypnoscript-documentation", + "version": "1.0.0", + "private": true, + "type": "module", + "scripts": { + "dev": "vitepress dev docs", + "build": "vitepress build docs", + "preview": "vitepress preview docs", + "serve": "vitepress preview docs" + }, + "dependencies": { + "vue": "^3.4.21" + }, + "devDependencies": { + "vitepress": "^1.5.0", + "typescript": "^5.3.3" + }, + "engines": { + "node": ">=18.0" + }, + "description": "Vollständige Dokumentation für HypnoScript - Die hypnotische Programmiersprache", + "keywords": [ + "hypnoscript", + "programming-language", + "documentation", + "docusaurus", + "hypnotic", + "german" + ], + "author": "HypnoScript Team", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/Kink-Development-Group/hyp-runtime.git", + "directory": "HypnoScript.Dokumentation" + }, + "homepage": "https://Kink-Development-Group.github.io/hyp-runtime/" +} diff --git a/HypnoScript.Dokumentation/static/.nojekyll b/hypnoscript-docs/static/.nojekyll similarity index 100% rename from HypnoScript.Dokumentation/static/.nojekyll rename to hypnoscript-docs/static/.nojekyll diff --git a/HypnoScript.Dokumentation/static/downloads/HypnoScript.Core.dll b/hypnoscript-docs/static/downloads/HypnoScript.Core.dll similarity index 100% rename from HypnoScript.Dokumentation/static/downloads/HypnoScript.Core.dll rename to hypnoscript-docs/static/downloads/HypnoScript.Core.dll diff --git a/HypnoScript.Dokumentation/static/downloads/HypnoScript.Runtime.deps.json b/hypnoscript-docs/static/downloads/HypnoScript.Runtime.deps.json similarity index 100% rename from HypnoScript.Dokumentation/static/downloads/HypnoScript.Runtime.deps.json rename to hypnoscript-docs/static/downloads/HypnoScript.Runtime.deps.json diff --git a/HypnoScript.Dokumentation/static/downloads/HypnoScript.Runtime.dll b/hypnoscript-docs/static/downloads/HypnoScript.Runtime.dll similarity index 100% rename from HypnoScript.Dokumentation/static/downloads/HypnoScript.Runtime.dll rename to hypnoscript-docs/static/downloads/HypnoScript.Runtime.dll diff --git a/hypnoscript-docs/static/img/android-chrome-192x192.png b/hypnoscript-docs/static/img/android-chrome-192x192.png new file mode 100644 index 0000000..1c0c2ed Binary files /dev/null and b/hypnoscript-docs/static/img/android-chrome-192x192.png differ diff --git a/hypnoscript-docs/static/img/android-chrome-512x512.png b/hypnoscript-docs/static/img/android-chrome-512x512.png new file mode 100644 index 0000000..cab20d8 Binary files /dev/null and b/hypnoscript-docs/static/img/android-chrome-512x512.png differ diff --git a/hypnoscript-docs/static/img/apple-touch-icon.png b/hypnoscript-docs/static/img/apple-touch-icon.png new file mode 100644 index 0000000..9d99e5d Binary files /dev/null and b/hypnoscript-docs/static/img/apple-touch-icon.png differ diff --git a/hypnoscript-docs/static/img/favicon-16x16.png b/hypnoscript-docs/static/img/favicon-16x16.png new file mode 100644 index 0000000..5b31bad Binary files /dev/null and b/hypnoscript-docs/static/img/favicon-16x16.png differ diff --git a/hypnoscript-docs/static/img/favicon-32x32.png b/hypnoscript-docs/static/img/favicon-32x32.png new file mode 100644 index 0000000..a335bda Binary files /dev/null and b/hypnoscript-docs/static/img/favicon-32x32.png differ diff --git a/hypnoscript-docs/static/img/favicon.ico b/hypnoscript-docs/static/img/favicon.ico new file mode 100644 index 0000000..1cde30e Binary files /dev/null and b/hypnoscript-docs/static/img/favicon.ico differ diff --git a/HypnoScript.Dokumentation/static/img/logo.svg b/hypnoscript-docs/static/img/logo.svg similarity index 100% rename from HypnoScript.Dokumentation/static/img/logo.svg rename to hypnoscript-docs/static/img/logo.svg diff --git a/hypnoscript-docs/static/img/site.webmanifest b/hypnoscript-docs/static/img/site.webmanifest new file mode 100644 index 0000000..45dc8a2 --- /dev/null +++ b/hypnoscript-docs/static/img/site.webmanifest @@ -0,0 +1 @@ +{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} \ No newline at end of file diff --git a/hypnoscript-lexer-parser/Cargo.toml b/hypnoscript-lexer-parser/Cargo.toml new file mode 100644 index 0000000..c1ef0b9 --- /dev/null +++ b/hypnoscript-lexer-parser/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "hypnoscript-lexer-parser" +version.workspace = true +edition.workspace = true +authors.workspace = true +license.workspace = true +repository.workspace = true + +[dependencies] +hypnoscript-core = { path = "../hypnoscript-core" } +serde = { workspace = true } +serde_json = { workspace = true } +once_cell = "1" diff --git a/hypnoscript-lexer-parser/src/ast.rs b/hypnoscript-lexer-parser/src/ast.rs new file mode 100644 index 0000000..183db29 --- /dev/null +++ b/hypnoscript-lexer-parser/src/ast.rs @@ -0,0 +1,244 @@ +use serde::{Deserialize, Serialize}; + +/// AST node types for HypnoScript +/// +/// This enum represents all possible Abstract Syntax Tree nodes in the HypnoScript language. +/// HypnoScript is an esoteric, TypeScript-inspired language with hypnotic-themed keywords. +/// +/// # Language Concepts +/// +/// - **Focus/Relax**: Program boundaries (main block) +/// - **induce/implant/freeze**: Variable declarations (var/let/const equivalents) +/// - **suggestion/trigger**: Function declarations +/// - **session**: Class declarations +/// - **entrance/finale**: Constructor/destructor blocks +/// - **observe/whisper/command**: Output statements +/// - **anchor**: State snapshot/variable backup +/// - **oscillate**: Boolean toggle operation +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum AstNode { + // Program structure + Program(Vec), + FocusBlock(Vec), + EntranceBlock(Vec), // Constructor/setup block + FinaleBlock(Vec), // Destructor/cleanup block + + // Declarations + VariableDeclaration { + name: String, + type_annotation: Option, + initializer: Option>, + is_constant: bool, // true for 'freeze', false for 'induce'/'implant' + }, + + /// Anchor statement: saves the current value of a variable for later restoration + /// Example: anchor savedValue = currentValue; + AnchorDeclaration { + name: String, + source: Box, + }, + + FunctionDeclaration { + name: String, + parameters: Vec, + return_type: Option, + body: Vec, + }, + + /// Trigger declaration: event handler or callback function + /// Similar to function but specifically for event handling + TriggerDeclaration { + name: String, + parameters: Vec, + return_type: Option, + body: Vec, + }, + + SessionDeclaration { + name: String, + members: Vec, + }, + + // Statements + ExpressionStatement(Box), + + /// observe: Output with newline (like console.log) + ObserveStatement(Box), + + /// whisper: Output without newline + WhisperStatement(Box), + + /// command: Imperative output (usually uppercase/emphasized) + CommandStatement(Box), + + IfStatement { + condition: Box, + then_branch: Vec, + else_branch: Option>, + }, + + /// deepFocus: Enhanced if-statement with deeper scope + DeepFocusStatement { + condition: Box, + body: Vec, + }, + + WhileStatement { + condition: Box, + body: Vec, + }, + LoopStatement { + body: Vec, + }, + ReturnStatement(Option>), + BreakStatement, + ContinueStatement, + + /// oscillate: Toggle a boolean variable + /// Example: oscillate myFlag; + OscillateStatement { + target: Box, + }, + + // Expressions + NumberLiteral(f64), + StringLiteral(String), + BooleanLiteral(bool), + Identifier(String), + + BinaryExpression { + left: Box, + operator: String, + right: Box, + }, + + UnaryExpression { + operator: String, + operand: Box, + }, + + CallExpression { + callee: Box, + arguments: Vec, + }, + + MemberExpression { + object: Box, + property: String, + }, + + ArrayLiteral(Vec), + + IndexExpression { + object: Box, + index: Box, + }, + + AssignmentExpression { + target: Box, + value: Box, + }, +} + +/// Function parameter +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct Parameter { + pub name: String, + pub type_annotation: Option, +} + +impl Parameter { + pub fn new(name: String, type_annotation: Option) -> Self { + Self { + name, + type_annotation, + } + } +} + +impl AstNode { + /// Check if the node is an expression + pub fn is_expression(&self) -> bool { + matches!( + self, + AstNode::NumberLiteral(_) + | AstNode::StringLiteral(_) + | AstNode::BooleanLiteral(_) + | AstNode::Identifier(_) + | AstNode::BinaryExpression { .. } + | AstNode::UnaryExpression { .. } + | AstNode::CallExpression { .. } + | AstNode::MemberExpression { .. } + | AstNode::ArrayLiteral(_) + | AstNode::IndexExpression { .. } + | AstNode::AssignmentExpression { .. } + ) + } + + /// Check if the node is a statement + pub fn is_statement(&self) -> bool { + matches!( + self, + AstNode::ExpressionStatement(_) + | AstNode::ObserveStatement(_) + | AstNode::WhisperStatement(_) + | AstNode::CommandStatement(_) + | AstNode::IfStatement { .. } + | AstNode::DeepFocusStatement { .. } + | AstNode::WhileStatement { .. } + | AstNode::LoopStatement { .. } + | AstNode::ReturnStatement(_) + | AstNode::BreakStatement + | AstNode::ContinueStatement + | AstNode::OscillateStatement { .. } + ) + } + + /// Check if the node is a declaration + pub fn is_declaration(&self) -> bool { + matches!( + self, + AstNode::VariableDeclaration { .. } + | AstNode::AnchorDeclaration { .. } + | AstNode::FunctionDeclaration { .. } + | AstNode::TriggerDeclaration { .. } + | AstNode::SessionDeclaration { .. } + ) + } +} + +/// Visibility for session members +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] +pub enum SessionVisibility { + Public, + Private, +} + +/// Members that may appear inside a session declaration +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum SessionMember { + Field(SessionField), + Method(SessionMethod), +} + +/// Session field definition within the AST +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct SessionField { + pub name: String, + pub type_annotation: Option, + pub initializer: Option>, + pub visibility: SessionVisibility, + pub is_static: bool, +} + +/// Session method definition within the AST +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct SessionMethod { + pub name: String, + pub parameters: Vec, + pub return_type: Option, + pub body: Vec, + pub visibility: SessionVisibility, + pub is_static: bool, + pub is_constructor: bool, +} diff --git a/hypnoscript-lexer-parser/src/lexer.rs b/hypnoscript-lexer-parser/src/lexer.rs new file mode 100644 index 0000000..370468b --- /dev/null +++ b/hypnoscript-lexer-parser/src/lexer.rs @@ -0,0 +1,437 @@ +use crate::token::{Token, TokenType}; + +/// Lexer for the HypnoScript language +pub struct Lexer { + source: Vec, + pos: usize, + line: usize, + column: usize, +} + +impl Lexer { + /// Create a new lexer + pub fn new(source: &str) -> Self { + Self { + source: source.chars().collect(), + pos: 0, + line: 1, + column: 1, + } + } + + /// Tokenize the source code + pub fn lex(&mut self) -> Result, String> { + let mut tokens = Vec::new(); + + while !self.is_at_end() { + self.skip_whitespace(); + if self.is_at_end() { + break; + } + + let start_column = self.column; + let c = self.advance(); + + if c.is_alphabetic() || c == '_' { + let ident = self.read_identifier(c); + let (token_type, lexeme) = self.keyword_or_identifier(&ident); + tokens.push(Token::new(token_type, lexeme, self.line, start_column)); + } else if c.is_numeric() { + let number = self.read_number(c); + tokens.push(Token::new( + TokenType::NumberLiteral, + number, + self.line, + start_column, + )); + } else { + match c { + '=' => { + if self.match_char('=') { + tokens.push(Token::new( + TokenType::DoubleEquals, + "==".to_string(), + self.line, + start_column, + )); + } else { + tokens.push(Token::new( + TokenType::Equals, + "=".to_string(), + self.line, + start_column, + )); + } + } + '+' => tokens.push(Token::new( + TokenType::Plus, + "+".to_string(), + self.line, + start_column, + )), + '-' => tokens.push(Token::new( + TokenType::Minus, + "-".to_string(), + self.line, + start_column, + )), + '*' => tokens.push(Token::new( + TokenType::Asterisk, + "*".to_string(), + self.line, + start_column, + )), + '/' => { + if self.match_char('/') { + self.skip_line_comment(); + } else if self.match_char('*') { + self.skip_block_comment(); + } else { + tokens.push(Token::new( + TokenType::Slash, + "/".to_string(), + self.line, + start_column, + )); + } + } + '%' => tokens.push(Token::new( + TokenType::Percent, + "%".to_string(), + self.line, + start_column, + )), + '>' => { + if self.match_char('=') { + tokens.push(Token::new( + TokenType::GreaterEqual, + ">=".to_string(), + self.line, + start_column, + )); + } else { + tokens.push(Token::new( + TokenType::Greater, + ">".to_string(), + self.line, + start_column, + )); + } + } + '<' => { + if self.match_char('=') { + tokens.push(Token::new( + TokenType::LessEqual, + "<=".to_string(), + self.line, + start_column, + )); + } else { + tokens.push(Token::new( + TokenType::Less, + "<".to_string(), + self.line, + start_column, + )); + } + } + '!' => { + if self.match_char('=') { + tokens.push(Token::new( + TokenType::NotEquals, + "!=".to_string(), + self.line, + start_column, + )); + } else { + tokens.push(Token::new( + TokenType::Bang, + "!".to_string(), + self.line, + start_column, + )); + } + } + '&' => { + if self.match_char('&') { + tokens.push(Token::new( + TokenType::AmpAmp, + "&&".to_string(), + self.line, + start_column, + )); + } + } + '|' => { + if self.match_char('|') { + tokens.push(Token::new( + TokenType::PipePipe, + "||".to_string(), + self.line, + start_column, + )); + } + } + ';' => tokens.push(Token::new( + TokenType::Semicolon, + ";".to_string(), + self.line, + start_column, + )), + ',' => tokens.push(Token::new( + TokenType::Comma, + ",".to_string(), + self.line, + start_column, + )), + '(' => tokens.push(Token::new( + TokenType::LParen, + "(".to_string(), + self.line, + start_column, + )), + ')' => tokens.push(Token::new( + TokenType::RParen, + ")".to_string(), + self.line, + start_column, + )), + '{' => tokens.push(Token::new( + TokenType::LBrace, + "{".to_string(), + self.line, + start_column, + )), + '}' => tokens.push(Token::new( + TokenType::RBrace, + "}".to_string(), + self.line, + start_column, + )), + '[' => tokens.push(Token::new( + TokenType::LBracket, + "[".to_string(), + self.line, + start_column, + )), + ']' => tokens.push(Token::new( + TokenType::RBracket, + "]".to_string(), + self.line, + start_column, + )), + ':' => tokens.push(Token::new( + TokenType::Colon, + ":".to_string(), + self.line, + start_column, + )), + '.' => tokens.push(Token::new( + TokenType::Dot, + ".".to_string(), + self.line, + start_column, + )), + '"' => { + let string_val = self.read_string()?; + tokens.push(Token::new( + TokenType::StringLiteral, + string_val, + self.line, + start_column, + )); + } + _ => { + return Err(format!( + "Unexpected character '{}' at line {}, column {}", + c, self.line, self.column + )) + } + } + } + } + + tokens.push(Token::new( + TokenType::Eof, + "".to_string(), + self.line, + self.column, + )); + Ok(tokens) + } + + fn is_at_end(&self) -> bool { + self.pos >= self.source.len() + } + + fn advance(&mut self) -> char { + let c = self.source[self.pos]; + self.pos += 1; + self.column += 1; + c + } + + fn peek(&self) -> char { + if self.is_at_end() { + '\0' + } else { + self.source[self.pos] + } + } + + fn match_char(&mut self, expected: char) -> bool { + if self.is_at_end() || self.peek() != expected { + false + } else { + self.advance(); + true + } + } + + fn skip_whitespace(&mut self) { + while !self.is_at_end() { + let c = self.peek(); + if c.is_whitespace() { + if c == '\n' { + self.line += 1; + self.column = 0; + } + self.advance(); + } else { + break; + } + } + } + + fn skip_line_comment(&mut self) { + while !self.is_at_end() && self.peek() != '\n' { + self.advance(); + } + } + + fn skip_block_comment(&mut self) { + while !self.is_at_end() { + if self.peek() == '*' { + self.advance(); + if !self.is_at_end() && self.peek() == '/' { + self.advance(); + break; + } + } else { + if self.peek() == '\n' { + self.line += 1; + self.column = 0; + } + self.advance(); + } + } + } + + fn read_identifier(&mut self, first: char) -> String { + let mut ident = String::new(); + ident.push(first); + + while !self.is_at_end() { + let c = self.peek(); + if c.is_alphanumeric() || c == '_' { + ident.push(c); + self.advance(); + } else { + break; + } + } + + ident + } + + fn read_number(&mut self, first: char) -> String { + let mut number = String::new(); + number.push(first); + + while !self.is_at_end() { + let c = self.peek(); + if c.is_numeric() || c == '.' { + number.push(c); + self.advance(); + } else { + break; + } + } + + number + } + + fn read_string(&mut self) -> Result { + let mut string = String::new(); + + while !self.is_at_end() { + let c = self.peek(); + if c == '"' { + self.advance(); + return Ok(string); + } else if c == '\\' { + self.advance(); + if !self.is_at_end() { + let escaped = self.advance(); + match escaped { + 'n' => string.push('\n'), + 't' => string.push('\t'), + 'r' => string.push('\r'), + '\\' => string.push('\\'), + '"' => string.push('"'), + _ => string.push(escaped), + } + } + } else { + if c == '\n' { + self.line += 1; + self.column = 0; + } + string.push(c); + self.advance(); + } + } + + Err(format!("Unterminated string at line {}", self.line)) + } + + fn keyword_or_identifier(&self, s: &str) -> (TokenType, String) { + if let Some(definition) = TokenType::keyword_definition(s) { + (definition.token, definition.canonical_lexeme.to_string()) + } else { + (TokenType::Identifier, s.to_string()) + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_simple_tokens() { + let mut lexer = Lexer::new("induce x: number = 42;"); + let tokens = lexer.lex().unwrap(); + assert!(!tokens.is_empty()); + assert_eq!(tokens[0].token_type, TokenType::Induce); + } + + #[test] + fn test_string_literal() { + let mut lexer = Lexer::new(r#""Hello, World!""#); + let tokens = lexer.lex().unwrap(); + assert_eq!(tokens[0].token_type, TokenType::StringLiteral); + assert_eq!(tokens[0].lexeme, "Hello, World!"); + } + + #[test] + fn test_operator_synonym_tokenization() { + let mut lexer = Lexer::new("if (a youAreFeelingVerySleepy b) { }"); + let tokens = lexer.lex().unwrap(); + let synonym = tokens + .iter() + .find(|token| token.token_type == TokenType::YouAreFeelingVerySleepy) + .expect("synonym token not found"); + assert_eq!(synonym.lexeme, "youAreFeelingVerySleepy"); + } +} diff --git a/hypnoscript-lexer-parser/src/lib.rs b/hypnoscript-lexer-parser/src/lib.rs new file mode 100644 index 0000000..e6ee590 --- /dev/null +++ b/hypnoscript-lexer-parser/src/lib.rs @@ -0,0 +1,13 @@ +//! HypnoScript Lexer and Parser Library +//! +//! This module provides the lexer and parser for the HypnoScript language. + +pub mod ast; +pub mod lexer; +pub mod parser; +pub mod token; + +// Re-export commonly used types +pub use lexer::Lexer; +pub use parser::Parser; +pub use token::{Token, TokenType}; diff --git a/hypnoscript-lexer-parser/src/parser.rs b/hypnoscript-lexer-parser/src/parser.rs new file mode 100644 index 0000000..52ba0a4 --- /dev/null +++ b/hypnoscript-lexer-parser/src/parser.rs @@ -0,0 +1,984 @@ +use crate::ast::{ + AstNode, Parameter, SessionField, SessionMember, SessionMethod, SessionVisibility, +}; +use crate::token::{Token, TokenType}; + +/// Parser for HypnoScript language +pub struct Parser { + tokens: Vec, + current: usize, +} + +impl Parser { + /// Create a new parser + pub fn new(tokens: Vec) -> Self { + Self { tokens, current: 0 } + } + + /// Parse a complete program + pub fn parse_program(&mut self) -> Result { + // Program must start with Focus + if !self.check(&TokenType::Focus) { + return Err("Program must start with 'Focus'".to_string()); + } + self.advance(); + + // Expect opening brace + if !self.match_token(&TokenType::LBrace) { + return Err("Expected '{' after 'Focus'".to_string()); + } + + // Parse program body + let statements = self.parse_block_statements()?; + + // Expect closing brace + if !self.match_token(&TokenType::RBrace) { + return Err("Expected '}' before 'Relax'".to_string()); + } + + // Program must end with Relax + if !self.check(&TokenType::Relax) { + return Err("Program must end with 'Relax'".to_string()); + } + self.advance(); + + Ok(AstNode::Program(statements)) + } + + /// Parse block statements + fn parse_block_statements(&mut self) -> Result, String> { + let mut statements = Vec::new(); + + while !self.is_at_end() && !self.check(&TokenType::RBrace) && !self.check(&TokenType::Relax) + { + // entrance block (constructor/setup) + if self.match_token(&TokenType::Entrance) { + if !self.match_token(&TokenType::LBrace) { + return Err("Expected '{' after 'entrance'".to_string()); + } + let mut entrance_statements = Vec::new(); + while !self.is_at_end() && !self.check(&TokenType::RBrace) { + entrance_statements.push(self.parse_statement()?); + } + if !self.match_token(&TokenType::RBrace) { + return Err("Expected '}' after entrance block".to_string()); + } + statements.push(AstNode::EntranceBlock(entrance_statements)); + continue; + } + + // finale block (destructor/cleanup) + if self.match_token(&TokenType::Finale) { + if !self.match_token(&TokenType::LBrace) { + return Err("Expected '{' after 'finale'".to_string()); + } + let mut finale_statements = Vec::new(); + while !self.is_at_end() && !self.check(&TokenType::RBrace) { + finale_statements.push(self.parse_statement()?); + } + if !self.match_token(&TokenType::RBrace) { + return Err("Expected '}' after finale block".to_string()); + } + statements.push(AstNode::FinaleBlock(finale_statements)); + continue; + } + + statements.push(self.parse_statement()?); + } + + Ok(statements) + } + + /// Parse a single statement + fn parse_statement(&mut self) -> Result { + // Variable declaration - induce, implant, freeze + if self.match_token(&TokenType::Induce) + || self.match_token(&TokenType::Implant) + || self.match_token(&TokenType::Freeze) + { + return self.parse_var_declaration(); + } + + // Anchor declaration - saves variable state + if self.match_token(&TokenType::Anchor) { + return self.parse_anchor_declaration(); + } + + // If statement + if self.match_token(&TokenType::If) { + return self.parse_if_statement(); + } + + // While loop + if self.match_token(&TokenType::While) { + return self.parse_while_statement(); + } + + // Loop + if self.match_token(&TokenType::Loop) { + return self.parse_loop_statement(); + } + + // Function declaration + if self.match_token(&TokenType::Suggestion) { + return self.parse_function_declaration(); + } + + // Trigger declaration (event handler/callback) + if self.match_token(&TokenType::Trigger) { + return self.parse_trigger_declaration(); + } + + // Session declaration + if self.match_token(&TokenType::Session) { + return self.parse_session_declaration(); + } + + // Output statements + if self.match_token(&TokenType::Observe) { + return self.parse_observe_statement(); + } + + if self.match_token(&TokenType::Whisper) { + return self.parse_whisper_statement(); + } + + if self.match_token(&TokenType::Command) { + return self.parse_command_statement(); + } + + // Return statement + if self.match_token(&TokenType::Awaken) { + return self.parse_return_statement(); + } + + // Break + if self.match_token(&TokenType::Snap) { + self.consume(&TokenType::Semicolon, "Expected ';' after 'snap'")?; + return Ok(AstNode::BreakStatement); + } + + // Continue + if self.match_token(&TokenType::Sink) { + self.consume(&TokenType::Semicolon, "Expected ';' after 'sink'")?; + return Ok(AstNode::ContinueStatement); + } + + // Oscillate statement (toggle boolean) + if self.match_token(&TokenType::Oscillate) { + return self.parse_oscillate_statement(); + } + + // Expression statement + let expr = self.parse_expression()?; + self.consume(&TokenType::Semicolon, "Expected ';' after expression")?; + Ok(AstNode::ExpressionStatement(Box::new(expr))) + } + + /// Parse variable declaration (induce/implant/freeze) + /// - induce: standard variable (like let/var) + /// - implant: alternative variable declaration + /// - freeze: constant (like const) + fn parse_var_declaration(&mut self) -> Result { + // Determine if this is a constant (freeze) or variable (induce/implant) + let is_constant = self.previous().token_type == TokenType::Freeze; + + let name = self + .consume(&TokenType::Identifier, "Expected variable name")? + .lexeme + .clone(); + + let type_annotation = if self.match_token(&TokenType::Colon) { + let type_token = self.advance(); + Some(type_token.lexeme.clone()) + } else { + None + }; + + let initializer = if self.match_token(&TokenType::Equals) { + Some(Box::new(self.parse_expression()?)) + } else { + None + }; + + self.consume( + &TokenType::Semicolon, + "Expected ';' after variable declaration", + )?; + + Ok(AstNode::VariableDeclaration { + name, + type_annotation, + initializer, + is_constant, + }) + } + + /// Parse anchor declaration (saves variable state) + /// Example: anchor savedValue = currentValue; + fn parse_anchor_declaration(&mut self) -> Result { + let name = self + .consume(&TokenType::Identifier, "Expected anchor name")? + .lexeme + .clone(); + + self.consume(&TokenType::Equals, "Expected '=' after anchor name")?; + + let source = Box::new(self.parse_expression()?); + + self.consume( + &TokenType::Semicolon, + "Expected ';' after anchor declaration", + )?; + + Ok(AstNode::AnchorDeclaration { name, source }) + } + + /// Parse oscillate statement (toggle boolean) + /// Example: oscillate myFlag; + fn parse_oscillate_statement(&mut self) -> Result { + let target = Box::new(self.parse_primary()?); + + self.consume( + &TokenType::Semicolon, + "Expected ';' after oscillate statement", + )?; + + Ok(AstNode::OscillateStatement { target }) + } + + /// Parse whisper statement (output without newline) + fn parse_whisper_statement(&mut self) -> Result { + let expr = self.parse_expression()?; + self.consume(&TokenType::Semicolon, "Expected ';' after whisper")?; + Ok(AstNode::WhisperStatement(Box::new(expr))) + } + + /// Parse command statement (imperative output) + fn parse_command_statement(&mut self) -> Result { + let expr = self.parse_expression()?; + self.consume(&TokenType::Semicolon, "Expected ';' after command")?; + Ok(AstNode::CommandStatement(Box::new(expr))) + } + + /// Parse trigger declaration (event handler/callback) + fn parse_trigger_declaration(&mut self) -> Result { + let name = self + .consume(&TokenType::Identifier, "Expected trigger name")? + .lexeme + .clone(); + + self.consume(&TokenType::Equals, "Expected '=' after trigger name")?; + + // Expect 'suggestion' keyword for the function body + self.consume(&TokenType::Suggestion, "Expected 'suggestion' after '='")?; + + self.consume(&TokenType::LParen, "Expected '(' after 'suggestion'")?; + + // Parse parameters (inline to avoid duplication) + let mut parameters = Vec::new(); + if !self.check(&TokenType::RParen) { + loop { + let param_name = self + .consume(&TokenType::Identifier, "Expected parameter name")? + .lexeme + .clone(); + let type_annotation = if self.match_token(&TokenType::Colon) { + let type_token = self.advance(); + Some(type_token.lexeme.clone()) + } else { + None + }; + parameters.push(Parameter::new(param_name, type_annotation)); + + if !self.match_token(&TokenType::Comma) { + break; + } + } + } + + self.consume(&TokenType::RParen, "Expected ')' after parameters")?; + + // Optional return type + let return_type = if self.match_token(&TokenType::Colon) { + let type_token = self.advance(); + Some(type_token.lexeme.clone()) + } else { + None + }; + + // Parse body + self.consume(&TokenType::LBrace, "Expected '{' before trigger body")?; + let body = self.parse_block_statements()?; + self.consume(&TokenType::RBrace, "Expected '}' after trigger body")?; + + Ok(AstNode::TriggerDeclaration { + name, + parameters, + return_type, + body, + }) + } + + /// Parse if statement + fn parse_if_statement(&mut self) -> Result { + self.consume(&TokenType::LParen, "Expected '(' after 'if'")?; + let condition = Box::new(self.parse_expression()?); + self.consume(&TokenType::RParen, "Expected ')' after if condition")?; + + // Check for deepFocus keyword or just a block + self.match_token(&TokenType::DeepFocus); + + self.consume(&TokenType::LBrace, "Expected '{' after if condition")?; + let then_branch = self.parse_block_statements()?; + self.consume(&TokenType::RBrace, "Expected '}' after if block")?; + + let else_branch = if self.match_token(&TokenType::Else) { + if self.match_token(&TokenType::If) { + // else if + Some(vec![self.parse_if_statement()?]) + } else { + self.consume(&TokenType::LBrace, "Expected '{' after 'else'")?; + let else_statements = self.parse_block_statements()?; + self.consume(&TokenType::RBrace, "Expected '}' after else block")?; + Some(else_statements) + } + } else { + None + }; + + Ok(AstNode::IfStatement { + condition, + then_branch, + else_branch, + }) + } + + /// Parse while statement + fn parse_while_statement(&mut self) -> Result { + self.consume(&TokenType::LParen, "Expected '(' after 'while'")?; + let condition = Box::new(self.parse_expression()?); + self.consume(&TokenType::RParen, "Expected ')' after while condition")?; + + self.consume(&TokenType::LBrace, "Expected '{' after while condition")?; + let body = self.parse_block_statements()?; + self.consume(&TokenType::RBrace, "Expected '}' after while block")?; + + Ok(AstNode::WhileStatement { condition, body }) + } + + /// Parse loop statement + fn parse_loop_statement(&mut self) -> Result { + self.consume(&TokenType::LBrace, "Expected '{' after 'loop'")?; + let body = self.parse_block_statements()?; + self.consume(&TokenType::RBrace, "Expected '}' after loop block")?; + + Ok(AstNode::LoopStatement { body }) + } + + /// Parse function declaration + fn parse_function_declaration(&mut self) -> Result { + let name = self + .consume(&TokenType::Identifier, "Expected function name")? + .lexeme + .clone(); + + self.consume(&TokenType::LParen, "Expected '(' after function name")?; + + let mut parameters = Vec::new(); + if !self.check(&TokenType::RParen) { + loop { + let param_name = self + .consume(&TokenType::Identifier, "Expected parameter name")? + .lexeme + .clone(); + let type_annotation = if self.match_token(&TokenType::Colon) { + let type_token = self.advance(); + Some(type_token.lexeme.clone()) + } else { + None + }; + parameters.push(Parameter::new(param_name, type_annotation)); + + if !self.match_token(&TokenType::Comma) { + break; + } + } + } + + self.consume(&TokenType::RParen, "Expected ')' after parameters")?; + + let return_type = if self.match_token(&TokenType::Colon) { + let type_token = self.advance(); + Some(type_token.lexeme.clone()) + } else { + None + }; + + self.consume(&TokenType::LBrace, "Expected '{' after function signature")?; + let body = self.parse_block_statements()?; + self.consume(&TokenType::RBrace, "Expected '}' after function body")?; + + Ok(AstNode::FunctionDeclaration { + name, + parameters, + return_type, + body, + }) + } + + /// Parse session declaration + fn parse_session_declaration(&mut self) -> Result { + let name = self + .consume(&TokenType::Identifier, "Expected session name")? + .lexeme + .clone(); + + self.consume(&TokenType::LBrace, "Expected '{' after session name")?; + + let mut members = Vec::new(); + while !self.check(&TokenType::RBrace) && !self.is_at_end() { + members.push(self.parse_session_member()?); + } + + self.consume(&TokenType::RBrace, "Expected '}' after session body")?; + + Ok(AstNode::SessionDeclaration { name, members }) + } + + /// Parse an individual session member (field or method) + fn parse_session_member(&mut self) -> Result { + let mut is_static = false; + if self.match_token(&TokenType::Dominant) { + is_static = true; + } + + // Optional visibility modifiers + if self.check(&TokenType::Expose) || self.check(&TokenType::Conceal) { + let visibility_token = self.advance(); + let visibility = if visibility_token.token_type == TokenType::Expose { + SessionVisibility::Public + } else { + SessionVisibility::Private + }; + + if self.check(&TokenType::Suggestion) + || self.check(&TokenType::ImperativeSuggestion) + || self.check(&TokenType::DominantSuggestion) + { + return self.parse_session_method(is_static, Some(visibility)); + } else { + return self.parse_session_field(is_static, visibility); + } + } + + // No explicit visibility modifier => default to public + self.parse_session_method(is_static, Some(SessionVisibility::Public)) + } + + fn parse_session_field( + &mut self, + is_static: bool, + visibility: SessionVisibility, + ) -> Result { + let name = self + .consume(&TokenType::Identifier, "Expected field name in session")? + .lexeme + .clone(); + + let type_annotation = if self.match_token(&TokenType::Colon) { + let type_token = self.advance(); + Some(type_token.lexeme.clone()) + } else { + None + }; + + let initializer = if self.match_token(&TokenType::Equals) { + Some(Box::new(self.parse_expression()?)) + } else { + None + }; + + self.consume( + &TokenType::Semicolon, + "Expected ';' after session field declaration", + )?; + + Ok(SessionMember::Field(SessionField { + name, + type_annotation, + initializer, + visibility, + is_static, + })) + } + + fn parse_session_method( + &mut self, + mut is_static: bool, + visibility: Option, + ) -> Result { + let visibility = visibility.unwrap_or(SessionVisibility::Public); + + let method_token = if self.match_token(&TokenType::Suggestion) { + Some(TokenType::Suggestion) + } else if self.match_token(&TokenType::ImperativeSuggestion) { + Some(TokenType::ImperativeSuggestion) + } else if self.match_token(&TokenType::DominantSuggestion) { + is_static = true; + Some(TokenType::DominantSuggestion) + } else { + None + }; + + if method_token.is_none() { + return Err("Expected 'suggestion' inside session".to_string()); + } + + let mut is_constructor = false; + let name = if self.match_token(&TokenType::Constructor) { + is_constructor = true; + "constructor".to_string() + } else { + self.consume(&TokenType::Identifier, "Expected method name")? + .lexeme + .clone() + }; + + self.consume(&TokenType::LParen, "Expected '(' after method name")?; + + let mut parameters = Vec::new(); + if !self.check(&TokenType::RParen) { + loop { + let param_name = self + .consume(&TokenType::Identifier, "Expected parameter name")? + .lexeme + .clone(); + let type_annotation = if self.match_token(&TokenType::Colon) { + let type_token = self.advance(); + Some(type_token.lexeme.clone()) + } else { + None + }; + parameters.push(Parameter::new(param_name, type_annotation)); + + if !self.match_token(&TokenType::Comma) { + break; + } + } + } + + self.consume(&TokenType::RParen, "Expected ')' after parameters")?; + + let return_type = if self.match_token(&TokenType::Colon) { + let type_token = self.advance(); + Some(type_token.lexeme.clone()) + } else { + None + }; + + self.consume(&TokenType::LBrace, "Expected '{' after method signature")?; + let body = self.parse_block_statements()?; + self.consume(&TokenType::RBrace, "Expected '}' after method body")?; + + Ok(SessionMember::Method(SessionMethod { + name, + parameters, + return_type, + body, + visibility, + is_static, + is_constructor, + })) + } + + /// Parse observe statement + fn parse_observe_statement(&mut self) -> Result { + let expr = Box::new(self.parse_expression()?); + self.consume( + &TokenType::Semicolon, + "Expected ';' after observe statement", + )?; + Ok(AstNode::ObserveStatement(expr)) + } + + /// Parse return statement + fn parse_return_statement(&mut self) -> Result { + let value = if !self.check(&TokenType::Semicolon) { + Some(Box::new(self.parse_expression()?)) + } else { + None + }; + self.consume(&TokenType::Semicolon, "Expected ';' after return statement")?; + Ok(AstNode::ReturnStatement(value)) + } + + /// Parse expression + fn parse_expression(&mut self) -> Result { + self.parse_assignment() + } + + /// Parse assignment + fn parse_assignment(&mut self) -> Result { + let expr = self.parse_logical_or()?; + + if self.match_token(&TokenType::Equals) { + let value = Box::new(self.parse_assignment()?); + return Ok(AstNode::AssignmentExpression { + target: Box::new(expr), + value, + }); + } + + Ok(expr) + } + + /// Parse logical OR + fn parse_logical_or(&mut self) -> Result { + let mut left = self.parse_logical_and()?; + + while self.match_tokens(&[TokenType::PipePipe, TokenType::ResistanceIsFutile]) { + let operator = self.previous().lexeme.clone(); + let right = Box::new(self.parse_logical_and()?); + left = AstNode::BinaryExpression { + left: Box::new(left), + operator, + right, + }; + } + + Ok(left) + } + + /// Parse logical AND + fn parse_logical_and(&mut self) -> Result { + let mut left = self.parse_equality()?; + + while self.match_tokens(&[TokenType::AmpAmp, TokenType::UnderMyControl]) { + let operator = self.previous().lexeme.clone(); + let right = Box::new(self.parse_equality()?); + left = AstNode::BinaryExpression { + left: Box::new(left), + operator, + right, + }; + } + + Ok(left) + } + + /// Parse equality + fn parse_equality(&mut self) -> Result { + let mut left = self.parse_comparison()?; + + while self.match_tokens(&[ + TokenType::DoubleEquals, + TokenType::NotEquals, + TokenType::YouAreFeelingVerySleepy, + TokenType::YouCannotResist, + TokenType::NotSoDeep, + ]) { + let operator = self.previous().lexeme.clone(); + let right = Box::new(self.parse_comparison()?); + left = AstNode::BinaryExpression { + left: Box::new(left), + operator, + right, + }; + } + + Ok(left) + } + + /// Parse comparison + fn parse_comparison(&mut self) -> Result { + let mut left = self.parse_term()?; + + while self.match_tokens(&[ + TokenType::Greater, + TokenType::GreaterEqual, + TokenType::Less, + TokenType::LessEqual, + TokenType::LookAtTheWatch, + TokenType::FallUnderMySpell, + TokenType::YourEyesAreGettingHeavy, + TokenType::GoingDeeper, + TokenType::DeeplyGreater, + TokenType::DeeplyLess, + ]) { + let operator = self.previous().lexeme.clone(); + let right = Box::new(self.parse_term()?); + left = AstNode::BinaryExpression { + left: Box::new(left), + operator, + right, + }; + } + + Ok(left) + } + + /// Parse term (addition/subtraction) + fn parse_term(&mut self) -> Result { + let mut left = self.parse_factor()?; + + while self.match_tokens(&[TokenType::Plus, TokenType::Minus]) { + let operator = self.previous().lexeme.clone(); + let right = Box::new(self.parse_factor()?); + left = AstNode::BinaryExpression { + left: Box::new(left), + operator, + right, + }; + } + + Ok(left) + } + + /// Parse factor (multiplication/division/modulo) + fn parse_factor(&mut self) -> Result { + let mut left = self.parse_unary()?; + + while self.match_tokens(&[TokenType::Asterisk, TokenType::Slash, TokenType::Percent]) { + let operator = self.previous().lexeme.clone(); + let right = Box::new(self.parse_unary()?); + left = AstNode::BinaryExpression { + left: Box::new(left), + operator, + right, + }; + } + + Ok(left) + } + + /// Parse unary + fn parse_unary(&mut self) -> Result { + if self.match_tokens(&[TokenType::Bang, TokenType::Minus]) { + let operator = self.previous().lexeme.clone(); + let operand = Box::new(self.parse_unary()?); + return Ok(AstNode::UnaryExpression { operator, operand }); + } + + self.parse_call() + } + + /// Parse call expression + fn parse_call(&mut self) -> Result { + let mut expr = self.parse_primary()?; + + loop { + if self.match_token(&TokenType::LParen) { + expr = self.finish_call(expr)?; + } else if self.match_token(&TokenType::Dot) { + let property = self + .consume(&TokenType::Identifier, "Expected property name after '.'")? + .lexeme + .clone(); + expr = AstNode::MemberExpression { + object: Box::new(expr), + property, + }; + } else if self.match_token(&TokenType::LBracket) { + let index = Box::new(self.parse_expression()?); + self.consume(&TokenType::RBracket, "Expected ']' after array index")?; + expr = AstNode::IndexExpression { + object: Box::new(expr), + index, + }; + } else { + break; + } + } + + Ok(expr) + } + + /// Finish parsing a call expression + fn finish_call(&mut self, callee: AstNode) -> Result { + let mut arguments = Vec::new(); + + if !self.check(&TokenType::RParen) { + loop { + arguments.push(self.parse_expression()?); + if !self.match_token(&TokenType::Comma) { + break; + } + } + } + + self.consume(&TokenType::RParen, "Expected ')' after arguments")?; + + Ok(AstNode::CallExpression { + callee: Box::new(callee), + arguments, + }) + } + + /// Parse primary expression + fn parse_primary(&mut self) -> Result { + // Number literal + if self.check(&TokenType::NumberLiteral) { + let token = self.advance(); + let value = token + .lexeme + .parse::() + .map_err(|_| format!("Invalid number: {}", token.lexeme))?; + return Ok(AstNode::NumberLiteral(value)); + } + + // String literal + if self.check(&TokenType::StringLiteral) { + let token = self.advance(); + return Ok(AstNode::StringLiteral(token.lexeme.clone())); + } + + // Boolean literals + if self.match_token(&TokenType::True) { + return Ok(AstNode::BooleanLiteral(true)); + } + if self.match_token(&TokenType::False) { + return Ok(AstNode::BooleanLiteral(false)); + } + + // Identifier + if self.check(&TokenType::Identifier) { + let token = self.advance(); + return Ok(AstNode::Identifier(token.lexeme.clone())); + } + + // Array literal + if self.match_token(&TokenType::LBracket) { + let mut elements = Vec::new(); + if !self.check(&TokenType::RBracket) { + loop { + elements.push(self.parse_expression()?); + if !self.match_token(&TokenType::Comma) { + break; + } + } + } + self.consume(&TokenType::RBracket, "Expected ']' after array elements")?; + return Ok(AstNode::ArrayLiteral(elements)); + } + + // Grouped expression + if self.match_token(&TokenType::LParen) { + let expr = self.parse_expression()?; + self.consume(&TokenType::RParen, "Expected ')' after expression")?; + return Ok(expr); + } + + Err(format!("Unexpected token: {:?}", self.peek())) + } + + // Helper methods + fn match_token(&mut self, token_type: &TokenType) -> bool { + if self.check(token_type) { + self.advance(); + true + } else { + false + } + } + + fn match_tokens(&mut self, types: &[TokenType]) -> bool { + for t in types { + if self.check(t) { + self.advance(); + return true; + } + } + false + } + + fn check(&self, token_type: &TokenType) -> bool { + if self.is_at_end() { + false + } else { + &self.peek().token_type == token_type + } + } + + fn advance(&mut self) -> Token { + if !self.is_at_end() { + self.current += 1; + } + self.previous() + } + + fn is_at_end(&self) -> bool { + self.peek().token_type == TokenType::Eof + } + + fn peek(&self) -> &Token { + &self.tokens[self.current] + } + + fn previous(&self) -> Token { + self.tokens[self.current - 1].clone() + } + + fn consume(&mut self, token_type: &TokenType, message: &str) -> Result { + if self.check(token_type) { + Ok(self.advance()) + } else { + Err(format!("{} at line {}", message, self.peek().line)) + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::lexer::Lexer; + + #[test] + fn test_parse_simple_program() { + let source = r#" +Focus { + induce x: number = 42; + observe x; +} Relax +"#; + let mut lexer = Lexer::new(source); + let tokens = lexer.lex().unwrap(); + let mut parser = Parser::new(tokens); + let ast = parser.parse_program(); + assert!(ast.is_ok()); + } + + #[test] + fn test_parse_if_statement() { + let source = r#" +Focus { + induce x: number = 10; + if (x > 5) deepFocus { + observe "Greater"; + } +} Relax +"#; + let mut lexer = Lexer::new(source); + let tokens = lexer.lex().unwrap(); + let mut parser = Parser::new(tokens); + let ast = parser.parse_program(); + assert!(ast.is_ok()); + } + + #[test] + fn test_parse_hypnotic_operator_synonyms() { + let source = r#" +Focus { + induce x: number = 10; + if (x youAreFeelingVerySleepy 10 resistanceIsFutile x youCannotResist 5) deepFocus { + observe "Synonym branch"; + } +} Relax +"#; + let mut lexer = Lexer::new(source); + let tokens = lexer.lex().unwrap(); + let mut parser = Parser::new(tokens); + let ast = parser.parse_program(); + assert!(ast.is_ok()); + } +} diff --git a/hypnoscript-lexer-parser/src/token.rs b/hypnoscript-lexer-parser/src/token.rs new file mode 100644 index 0000000..eef9570 --- /dev/null +++ b/hypnoscript-lexer-parser/src/token.rs @@ -0,0 +1,705 @@ +use once_cell::sync::Lazy; +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; + +/// Token types in the HypnoScript language +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub enum TokenType { + // Basic program structure + Focus, + Relax, + Entrance, + Finale, // Destructor/cleanup block + DeepFocus, // Deep focus block modifier + + // Variables and declarations + Induce, // Variable declaration (standard) + Implant, // Variable declaration (alternative) + Freeze, // Constant declaration + From, + External, + Anchor, // Save state/create snapshot + + // Control structures + If, + Else, + While, + Loop, + Snap, // break + Sink, // continue + SinkTo, // goto + Oscillate, // toggle boolean + + // Functions + Suggestion, // Standard function + Trigger, // Event handler/callback function + ImperativeSuggestion, // Imperative function modifier + DominantSuggestion, // Static function modifier + Awaken, // return + Call, + + // Object-oriented programming + Session, + Constructor, + Expose, // public + Conceal, // private + Dominant, // static + + // Structures + Tranceify, + + // I/O + Observe, // Standard output with newline + Whisper, // Output without newline + Command, // Imperative output + Drift, // Sleep/delay + + // Hypnotic operators + YouAreFeelingVerySleepy, // == + YouCannotResist, // != + LookAtTheWatch, // > + FallUnderMySpell, // < + YourEyesAreGettingHeavy, // >= + GoingDeeper, // <= + NotSoDeep, // != (legacy) + DeeplyGreater, // >= (legacy) + DeeplyLess, // <= (legacy) + UnderMyControl, // && + ResistanceIsFutile, // || + + // Modules and globals + MindLink, // import + SharedTrance, // global + + // Labels + Label, + + // Standard operators + DoubleEquals, // == + NotEquals, // != + Greater, + GreaterEqual, // >= + Less, + LessEqual, // <= + Plus, + Minus, + Asterisk, + Slash, + Percent, + Bang, // ! + AmpAmp, // && + PipePipe, // || + + // Literals and identifiers + Identifier, + NumberLiteral, + StringLiteral, + BooleanLiteral, + + // Types + Number, + String, + Boolean, + Trance, + + // Boolean literals + True, + False, + + // Delimiters and brackets + LParen, // ( + RParen, // ) + LBrace, // { + RBrace, // } + LBracket, // [ + RBracket, // ] + Comma, + Colon, // : + Semicolon, // ; + Dot, // . + Equals, // = + + // End of file + Eof, + + // Assert statement + Assert, +} + +/// Metadata describing a keyword, including its canonical lexeme for normalization. +#[derive(Clone, Copy)] +pub struct KeywordDefinition { + pub token: TokenType, + pub canonical_lexeme: &'static str, +} + +/// All reserved words and hypnotic operator synonyms mapped by their normalized form. +static KEYWORD_DEFINITIONS: Lazy> = Lazy::new(|| { + use TokenType::*; + + let mut map = HashMap::with_capacity(64); + + // Core structure keywords + map.insert( + "focus", + KeywordDefinition { + token: Focus, + canonical_lexeme: "Focus", + }, + ); + map.insert( + "relax", + KeywordDefinition { + token: Relax, + canonical_lexeme: "Relax", + }, + ); + map.insert( + "entrance", + KeywordDefinition { + token: Entrance, + canonical_lexeme: "entrance", + }, + ); + map.insert( + "finale", + KeywordDefinition { + token: Finale, + canonical_lexeme: "finale", + }, + ); + map.insert( + "deepfocus", + KeywordDefinition { + token: DeepFocus, + canonical_lexeme: "deepFocus", + }, + ); + + // Variable declarations and sourcing + map.insert( + "induce", + KeywordDefinition { + token: Induce, + canonical_lexeme: "induce", + }, + ); + map.insert( + "implant", + KeywordDefinition { + token: Implant, + canonical_lexeme: "implant", + }, + ); + map.insert( + "freeze", + KeywordDefinition { + token: Freeze, + canonical_lexeme: "freeze", + }, + ); + map.insert( + "anchor", + KeywordDefinition { + token: Anchor, + canonical_lexeme: "anchor", + }, + ); + map.insert( + "from", + KeywordDefinition { + token: From, + canonical_lexeme: "from", + }, + ); + map.insert( + "external", + KeywordDefinition { + token: External, + canonical_lexeme: "external", + }, + ); + + // Control flow constructs + map.insert( + "if", + KeywordDefinition { + token: If, + canonical_lexeme: "if", + }, + ); + map.insert( + "else", + KeywordDefinition { + token: Else, + canonical_lexeme: "else", + }, + ); + map.insert( + "while", + KeywordDefinition { + token: While, + canonical_lexeme: "while", + }, + ); + map.insert( + "loop", + KeywordDefinition { + token: Loop, + canonical_lexeme: "loop", + }, + ); + map.insert( + "snap", + KeywordDefinition { + token: Snap, + canonical_lexeme: "snap", + }, + ); + map.insert( + "break", + KeywordDefinition { + token: Snap, + canonical_lexeme: "snap", + }, + ); + map.insert( + "sink", + KeywordDefinition { + token: Sink, + canonical_lexeme: "sink", + }, + ); + map.insert( + "continue", + KeywordDefinition { + token: Sink, + canonical_lexeme: "sink", + }, + ); + map.insert( + "sinkto", + KeywordDefinition { + token: SinkTo, + canonical_lexeme: "sinkTo", + }, + ); + map.insert( + "oscillate", + KeywordDefinition { + token: Oscillate, + canonical_lexeme: "oscillate", + }, + ); + + // Functions + map.insert( + "suggestion", + KeywordDefinition { + token: Suggestion, + canonical_lexeme: "suggestion", + }, + ); + map.insert( + "trigger", + KeywordDefinition { + token: Trigger, + canonical_lexeme: "trigger", + }, + ); + map.insert( + "imperativesuggestion", + KeywordDefinition { + token: ImperativeSuggestion, + canonical_lexeme: "imperativeSuggestion", + }, + ); + map.insert( + "dominantsuggestion", + KeywordDefinition { + token: DominantSuggestion, + canonical_lexeme: "dominantSuggestion", + }, + ); + map.insert( + "awaken", + KeywordDefinition { + token: Awaken, + canonical_lexeme: "awaken", + }, + ); + map.insert( + "return", + KeywordDefinition { + token: Awaken, + canonical_lexeme: "awaken", + }, + ); + map.insert( + "call", + KeywordDefinition { + token: Call, + canonical_lexeme: "call", + }, + ); + + // Sessions (classes) + map.insert( + "session", + KeywordDefinition { + token: Session, + canonical_lexeme: "session", + }, + ); + map.insert( + "constructor", + KeywordDefinition { + token: Constructor, + canonical_lexeme: "constructor", + }, + ); + map.insert( + "expose", + KeywordDefinition { + token: Expose, + canonical_lexeme: "expose", + }, + ); + map.insert( + "conceal", + KeywordDefinition { + token: Conceal, + canonical_lexeme: "conceal", + }, + ); + map.insert( + "dominant", + KeywordDefinition { + token: Dominant, + canonical_lexeme: "dominant", + }, + ); + + // Structures and observations + map.insert( + "tranceify", + KeywordDefinition { + token: Tranceify, + canonical_lexeme: "tranceify", + }, + ); + map.insert( + "observe", + KeywordDefinition { + token: Observe, + canonical_lexeme: "observe", + }, + ); + map.insert( + "whisper", + KeywordDefinition { + token: Whisper, + canonical_lexeme: "whisper", + }, + ); + map.insert( + "command", + KeywordDefinition { + token: Command, + canonical_lexeme: "command", + }, + ); + map.insert( + "drift", + KeywordDefinition { + token: Drift, + canonical_lexeme: "drift", + }, + ); + + // Modules and globals + map.insert( + "mindlink", + KeywordDefinition { + token: MindLink, + canonical_lexeme: "mindLink", + }, + ); + map.insert( + "sharedtrance", + KeywordDefinition { + token: SharedTrance, + canonical_lexeme: "sharedTrance", + }, + ); + map.insert( + "label", + KeywordDefinition { + token: Label, + canonical_lexeme: "label", + }, + ); + + // Operator synonyms (equality) + map.insert( + "youarefeelingverysleepy", + KeywordDefinition { + token: YouAreFeelingVerySleepy, + canonical_lexeme: "youAreFeelingVerySleepy", + }, + ); + map.insert( + "youcannotresist", + KeywordDefinition { + token: YouCannotResist, + canonical_lexeme: "youCannotResist", + }, + ); + map.insert( + "notsodeep", + KeywordDefinition { + token: NotSoDeep, + canonical_lexeme: "notSoDeep", + }, + ); + + // Operator synonyms (comparison) + map.insert( + "lookatthewatch", + KeywordDefinition { + token: LookAtTheWatch, + canonical_lexeme: "lookAtTheWatch", + }, + ); + map.insert( + "fallundermyspell", + KeywordDefinition { + token: FallUnderMySpell, + canonical_lexeme: "fallUnderMySpell", + }, + ); + map.insert( + "youreyesaregettingheavy", + KeywordDefinition { + token: YourEyesAreGettingHeavy, + canonical_lexeme: "yourEyesAreGettingHeavy", + }, + ); + map.insert( + "goingdeeper", + KeywordDefinition { + token: GoingDeeper, + canonical_lexeme: "goingDeeper", + }, + ); + map.insert( + "deeplygreater", + KeywordDefinition { + token: DeeplyGreater, + canonical_lexeme: "deeplyGreater", + }, + ); + map.insert( + "deeplyless", + KeywordDefinition { + token: DeeplyLess, + canonical_lexeme: "deeplyLess", + }, + ); + + // Logical operator synonyms + map.insert( + "undermycontrol", + KeywordDefinition { + token: UnderMyControl, + canonical_lexeme: "underMyControl", + }, + ); + map.insert( + "resistanceisfutile", + KeywordDefinition { + token: ResistanceIsFutile, + canonical_lexeme: "resistanceIsFutile", + }, + ); + + // Primitive type aliases and literals + map.insert( + "number", + KeywordDefinition { + token: Number, + canonical_lexeme: "number", + }, + ); + map.insert( + "string", + KeywordDefinition { + token: String, + canonical_lexeme: "string", + }, + ); + map.insert( + "boolean", + KeywordDefinition { + token: Boolean, + canonical_lexeme: "boolean", + }, + ); + map.insert( + "trance", + KeywordDefinition { + token: Trance, + canonical_lexeme: "trance", + }, + ); + map.insert( + "true", + KeywordDefinition { + token: True, + canonical_lexeme: "true", + }, + ); + map.insert( + "false", + KeywordDefinition { + token: False, + canonical_lexeme: "false", + }, + ); + + map.insert( + "assert", + KeywordDefinition { + token: Assert, + canonical_lexeme: "assert", + }, + ); + + map +}); + +impl TokenType { + /// Check if token is a keyword + pub fn is_keyword(&self) -> bool { + matches!( + self, + TokenType::Focus + | TokenType::Relax + | TokenType::Entrance + | TokenType::Finale + | TokenType::DeepFocus + | TokenType::Induce + | TokenType::Implant + | TokenType::Freeze + | TokenType::Anchor + | TokenType::From + | TokenType::External + | TokenType::If + | TokenType::Else + | TokenType::While + | TokenType::Loop + | TokenType::Snap + | TokenType::Sink + | TokenType::SinkTo + | TokenType::Oscillate + | TokenType::Suggestion + | TokenType::Trigger + | TokenType::ImperativeSuggestion + | TokenType::DominantSuggestion + | TokenType::Awaken + | TokenType::Call + | TokenType::Session + | TokenType::Constructor + | TokenType::Expose + | TokenType::Conceal + | TokenType::Dominant + | TokenType::Tranceify + | TokenType::Observe + | TokenType::Whisper + | TokenType::Command + | TokenType::Drift + | TokenType::MindLink + | TokenType::SharedTrance + | TokenType::Label + | TokenType::Assert + | TokenType::True + | TokenType::False + ) + } + + /// Check if token is an operator + pub fn is_operator(&self) -> bool { + matches!( + self, + TokenType::YouAreFeelingVerySleepy + | TokenType::YouCannotResist + | TokenType::LookAtTheWatch + | TokenType::FallUnderMySpell + | TokenType::YourEyesAreGettingHeavy + | TokenType::GoingDeeper + | TokenType::NotSoDeep + | TokenType::DeeplyGreater + | TokenType::DeeplyLess + | TokenType::DoubleEquals + | TokenType::NotEquals + | TokenType::Greater + | TokenType::GreaterEqual + | TokenType::Less + | TokenType::LessEqual + | TokenType::UnderMyControl + | TokenType::ResistanceIsFutile + | TokenType::Plus + | TokenType::Minus + | TokenType::Asterisk + | TokenType::Slash + | TokenType::Percent + | TokenType::Bang + | TokenType::AmpAmp + | TokenType::PipePipe + ) + } + + /// Check if token is a literal + pub fn is_literal(&self) -> bool { + matches!( + self, + TokenType::NumberLiteral + | TokenType::StringLiteral + | TokenType::BooleanLiteral + | TokenType::True + | TokenType::False + ) + } + + /// Lookup keyword definition by source lexeme. + pub fn keyword_definition(s: &str) -> Option { + let normalized = s.to_ascii_lowercase(); + KEYWORD_DEFINITIONS.get(normalized.as_str()).copied() + } + + /// Get keyword from string. + pub fn from_keyword(s: &str) -> Option { + Self::keyword_definition(s).map(|definition| definition.token) + } +} + +/// A token in the HypnoScript language +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct Token { + pub token_type: TokenType, + pub lexeme: String, + pub line: usize, + pub column: usize, +} + +impl Token { + /// Create a new token + pub fn new(token_type: TokenType, lexeme: String, line: usize, column: usize) -> Self { + Self { + token_type, + lexeme, + line, + column, + } + } +} diff --git a/hypnoscript-runtime/Cargo.toml b/hypnoscript-runtime/Cargo.toml new file mode 100644 index 0000000..e9860aa --- /dev/null +++ b/hypnoscript-runtime/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "hypnoscript-runtime" +version.workspace = true +edition.workspace = true +authors.workspace = true +license.workspace = true +repository.workspace = true + +[dependencies] +hypnoscript-core = { path = "../hypnoscript-core" } +serde = { workspace = true } +serde_json = { workspace = true } +anyhow = { workspace = true } +thiserror = { workspace = true } +chrono = "0.4" +regex = "1.10" +num_cpus = "1.16" +hostname = "0.4" diff --git a/hypnoscript-runtime/src/array_builtins.rs b/hypnoscript-runtime/src/array_builtins.rs new file mode 100644 index 0000000..28cc486 --- /dev/null +++ b/hypnoscript-runtime/src/array_builtins.rs @@ -0,0 +1,154 @@ +/// Array/Vector builtin functions +pub struct ArrayBuiltins; + +impl ArrayBuiltins { + /// Get array length + pub fn length(arr: &[T]) -> usize { + arr.len() + } + + /// Check if array is empty + pub fn is_empty(arr: &[T]) -> bool { + arr.is_empty() + } + + /// Get element at index + pub fn get(arr: &[T], index: usize) -> Option { + arr.get(index).cloned() + } + + /// Find index of element + pub fn index_of(arr: &[T], element: &T) -> i64 { + arr.iter() + .position(|x| x == element) + .map(|i| i as i64) + .unwrap_or(-1) + } + + /// Check if array contains element + pub fn contains(arr: &[T], element: &T) -> bool { + arr.contains(element) + } + + /// Reverse array + pub fn reverse(arr: &[T]) -> Vec { + arr.iter().rev().cloned().collect() + } + + /// Get sum of numeric array + pub fn sum(arr: &[f64]) -> f64 { + arr.iter().sum() + } + + /// Get average of numeric array + pub fn average(arr: &[f64]) -> f64 { + if arr.is_empty() { + 0.0 + } else { + Self::sum(arr) / arr.len() as f64 + } + } + + /// Get minimum value + pub fn min(arr: &[f64]) -> f64 { + arr.iter().fold(f64::INFINITY, |a, &b| a.min(b)) + } + + /// Get maximum value + pub fn max(arr: &[f64]) -> f64 { + arr.iter().fold(f64::NEG_INFINITY, |a, &b| a.max(b)) + } + + /// Sort array (ascending) + pub fn sort(arr: &[f64]) -> Vec { + let mut sorted = arr.to_vec(); + sorted.sort_by(|a, b| a.partial_cmp(b).unwrap()); + sorted + } + + /// Get first element + pub fn first(arr: &[T]) -> Option { + arr.first().cloned() + } + + /// Get last element + pub fn last(arr: &[T]) -> Option { + arr.last().cloned() + } + + /// Take first n elements + pub fn take(arr: &[T], n: usize) -> Vec { + arr.iter().take(n).cloned().collect() + } + + /// Skip first n elements + pub fn skip(arr: &[T], n: usize) -> Vec { + arr.iter().skip(n).cloned().collect() + } + + /// Slice array + pub fn slice(arr: &[T], start: usize, end: usize) -> Vec { + let start = start.min(arr.len()); + let end = end.min(arr.len()); + if start >= end { + Vec::new() + } else { + arr[start..end].to_vec() + } + } + + /// Join array elements into string + pub fn join(arr: &[T], separator: &str) -> String { + arr.iter() + .map(|x| x.to_string()) + .collect::>() + .join(separator) + } + + /// Count occurrences of element + pub fn count(arr: &[T], element: &T) -> usize { + arr.iter().filter(|&x| x == element).count() + } + + /// Remove duplicates + pub fn distinct(arr: &[T]) -> Vec { + let mut result = Vec::new(); + for item in arr { + if !result.contains(item) { + result.push(item.clone()); + } + } + result + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_length() { + assert_eq!(ArrayBuiltins::length(&[1, 2, 3, 4, 5]), 5); + assert_eq!(ArrayBuiltins::length(&[] as &[i32]), 0); + } + + #[test] + fn test_sum() { + assert_eq!(ArrayBuiltins::sum(&[1.0, 2.0, 3.0, 4.0, 5.0]), 15.0); + } + + #[test] + fn test_average() { + assert_eq!(ArrayBuiltins::average(&[1.0, 2.0, 3.0, 4.0, 5.0]), 3.0); + } + + #[test] + fn test_reverse() { + assert_eq!(ArrayBuiltins::reverse(&[1, 2, 3]), vec![3, 2, 1]); + } + + #[test] + fn test_distinct() { + assert_eq!(ArrayBuiltins::distinct(&[1, 2, 2, 3, 3, 3]), vec![1, 2, 3]); + } +} diff --git a/hypnoscript-runtime/src/core_builtins.rs b/hypnoscript-runtime/src/core_builtins.rs new file mode 100644 index 0000000..7206ce8 --- /dev/null +++ b/hypnoscript-runtime/src/core_builtins.rs @@ -0,0 +1,117 @@ +use std::thread; +use std::time::Duration; + +/// Core I/O and hypnotic builtin functions +pub struct CoreBuiltins; + +impl CoreBuiltins { + /// Output a value with newline (observe) + /// Standard output function in HypnoScript + pub fn observe(value: &str) { + println!("{}", value); + } + + /// Output a value without newline (whisper) + /// Used for continuous output without line breaks + pub fn whisper(value: &str) { + print!("{}", value); + use std::io::{self, Write}; + let _ = io::stdout().flush(); + } + + /// Output a value in imperative/command style (command) + /// Typically outputs in uppercase or emphasized format + pub fn command(value: &str) { + println!("{}", value.to_uppercase()); + } + + /// Wait for specified milliseconds (drift) + pub fn drift(ms: u64) { + thread::sleep(Duration::from_millis(ms)); + } + + /// Deep trance induction + pub fn deep_trance(duration: u64) { + Self::observe("Entering deep trance..."); + Self::drift(duration); + Self::observe("Emerging from trance..."); + } + + /// Hypnotic countdown + pub fn hypnotic_countdown(from: i64) { + for i in (1..=from).rev() { + Self::observe(&format!("You are feeling very sleepy... {}", i)); + Self::drift(1000); + } + Self::observe("You are now in a deep hypnotic state."); + } + + /// Trance induction + pub fn trance_induction(subject_name: &str) { + Self::observe(&format!( + "Welcome {}, you are about to enter a deep trance...", + subject_name + )); + Self::drift(2000); + Self::observe("Take a deep breath and relax..."); + Self::drift(1500); + Self::observe("With each breath, you feel more and more relaxed..."); + Self::drift(1500); + Self::observe("Your mind is becoming clear and focused..."); + Self::drift(1000); + } + + /// Hypnotic visualization + pub fn hypnotic_visualization(scene: &str) { + Self::observe(&format!("Imagine yourself in {}...", scene)); + Self::drift(1500); + Self::observe("The colors are vivid, the sounds are clear..."); + Self::drift(1500); + Self::observe("You feel completely at peace in this place..."); + Self::drift(1000); + } + + /// Conversion functions + pub fn to_int(value: f64) -> i64 { + value as i64 + } + + pub fn to_double(value: &str) -> Result { + value.parse::().map_err(|e| e.to_string()) + } + + pub fn to_string(value: &dyn std::fmt::Display) -> String { + format!("{}", value) + } + + pub fn to_boolean(value: &str) -> bool { + matches!(value.to_lowercase().as_str(), "true" | "1" | "yes") + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_to_int() { + assert_eq!(CoreBuiltins::to_int(42.7), 42); + assert_eq!(CoreBuiltins::to_int(-5.2), -5); + } + + #[test] + fn test_to_double() { + // Test mit Werten, die nicht zu nahe an mathematischen Konstanten liegen + assert_eq!(CoreBuiltins::to_double("42.75").unwrap(), 42.75); + assert_eq!(CoreBuiltins::to_double("0.5").unwrap(), 0.5); + assert!(CoreBuiltins::to_double("invalid").is_err()); + } + + #[test] + fn test_to_boolean() { + assert!(CoreBuiltins::to_boolean("true")); + assert!(CoreBuiltins::to_boolean("True")); + assert!(CoreBuiltins::to_boolean("1")); + assert!(!CoreBuiltins::to_boolean("false")); + } +} diff --git a/hypnoscript-runtime/src/deepmind_builtins.rs b/hypnoscript-runtime/src/deepmind_builtins.rs new file mode 100644 index 0000000..b6dd06c --- /dev/null +++ b/hypnoscript-runtime/src/deepmind_builtins.rs @@ -0,0 +1,315 @@ +/// DeepMind Control Flow and Higher-Order Functions +/// +/// This module provides advanced control flow and functional programming constructs +/// for HypnoScript, including function composition, conditional execution, and +/// repetition utilities. +/// +/// # Language Integration +/// +/// These functions are designed to work with HypnoScript's hypnotic metaphors: +/// - `repeatAction`: Hypnotic repetition +/// - `delayedSuggestion`: Time-delayed execution +/// - `ifTranced`: Conditional execution as a function +/// - `compose`/`pipe`: Function composition +/// - `repeatUntil`/`repeatWhile`: Advanced loop constructs +/// - `tryOrAwaken`: Error handling +/// - `ensureAwakening`: Cleanup guarantee +use std::thread; +use std::time::Duration; + +/// Hypnotic Control Flow Functions +pub struct DeepMindBuiltins; + +impl DeepMindBuiltins { + /// Repeat an action a specific number of times + /// + /// # Example (HypnoScript) + /// ```hypnoscript + /// repeatAction(5, suggestion() { + /// observe "Om"; + /// }); + /// ``` + pub fn repeat_action(times: usize, mut action: F) + where + F: FnMut(), + { + for _ in 0..times { + action(); + } + } + + /// Execute an action after a delay (in milliseconds) + /// + /// # Example (HypnoScript) + /// ```hypnoscript + /// delayedSuggestion(suggestion() { + /// observe "Delayed message"; + /// }, 2000); + /// ``` + pub fn delayed_suggestion(action: F, delay_ms: u64) + where + F: FnOnce(), + { + thread::sleep(Duration::from_millis(delay_ms)); + action(); + } + + /// Conditional execution as a function + /// + /// # Example (HypnoScript) + /// ```hypnoscript + /// ifTranced(age >= 18, + /// suggestion() { observe "Adult"; }, + /// suggestion() { observe "Minor"; } + /// ); + /// ``` + pub fn if_tranced(condition: bool, then_action: T, else_action: E) + where + T: FnOnce(), + E: FnOnce(), + { + if condition { + then_action(); + } else { + else_action(); + } + } + + /// Compose two functions: f(g(x)) + /// + /// Returns a new function that applies g first, then f + /// + /// # Example (HypnoScript) + /// ```hypnoscript + /// induce composed = compose(double, addTen); + /// induce result = composed(5); // double(addTen(5)) = 30 + /// ``` + pub fn compose(f: F, g: G) -> impl Fn(A) -> C + where + F: Fn(B) -> C, + G: Fn(A) -> B, + { + move |x| f(g(x)) + } + + /// Pipe two functions: g(f(x)) + /// + /// Returns a new function that applies f first, then g + /// + /// # Example (HypnoScript) + /// ```hypnoscript + /// induce piped = pipe(double, addTen); + /// induce result = piped(5); // addTen(double(5)) = 20 + /// ``` + pub fn pipe(f: F, g: G) -> impl Fn(A) -> C + where + F: Fn(A) -> B, + G: Fn(B) -> C, + { + move |x| g(f(x)) + } + + /// Repeat until a condition becomes true + /// + /// # Example (HypnoScript) + /// ```hypnoscript + /// induce count = 0; + /// repeatUntil( + /// suggestion() { count = count + 1; }, + /// suggestion(): boolean { awaken count >= 5; } + /// ); + /// ``` + pub fn repeat_until(mut action: A, mut condition: C) + where + A: FnMut(), + C: FnMut() -> bool, + { + while !condition() { + action(); + } + } + + /// Repeat while a condition is true + /// + /// # Example (HypnoScript) + /// ```hypnoscript + /// induce n = 3; + /// repeatWhile( + /// suggestion(): boolean { awaken n > 0; }, + /// suggestion() { observe "Countdown: " + n; n = n - 1; } + /// ); + /// ``` + pub fn repeat_while(mut condition: C, mut action: A) + where + C: FnMut() -> bool, + A: FnMut(), + { + while condition() { + action(); + } + } + + /// Execute actions sequentially + /// + /// # Example (HypnoScript) + /// ```hypnoscript + /// induce actions = [ + /// suggestion() { observe "Step 1"; }, + /// suggestion() { observe "Step 2"; }, + /// suggestion() { observe "Step 3"; } + /// ]; + /// sequentialTrance(actions); + /// ``` + pub fn sequential_trance(actions: Vec) + where + F: FnOnce(), + { + for action in actions { + action(); + } + } + + /// Try-catch style error handling + /// + /// # Example (HypnoScript) + /// ```hypnoscript + /// tryOrAwaken( + /// suggestion() { + /// // risky operation + /// induce x = riskyFunction(); + /// }, + /// suggestion(error: string) { + /// observe "Error: " + error; + /// } + /// ); + /// ``` + pub fn try_or_awaken(try_action: T, catch_action: E) + where + T: FnOnce() -> Result<(), String>, + E: FnOnce(String), + { + if let Err(err) = try_action() { + catch_action(err); + } + } + + /// Ensure cleanup code runs (like try-finally) + /// + /// # Example (HypnoScript) + /// ```hypnoscript + /// ensureAwakening( + /// suggestion() { + /// observe "Main action"; + /// }, + /// suggestion() { + /// observe "Cleanup always runs"; + /// } + /// ); + /// ``` + pub fn ensure_awakening(main_action: M, cleanup: C) + where + M: FnOnce(), + C: FnOnce(), + { + main_action(); + cleanup(); + } + + /// Measure execution time of an action + /// + /// Returns the duration in milliseconds + pub fn measure_trance_depth(action: F) -> u128 + where + F: FnOnce(), + { + use std::time::Instant; + let start = Instant::now(); + action(); + start.elapsed().as_millis() + } + + /// Memoize/cache a function result + /// + /// Note: This is a simplified version for demonstration. + /// A real implementation would use a HashMap. + pub fn memoize(f: F) -> impl FnMut(A) -> R + where + F: Fn(A) -> R, + A: Clone, + R: Clone, + { + // Simplified: Just pass through + // A real memoization would cache results + move |x| f(x) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_repeat_action() { + let mut count = 0; + DeepMindBuiltins::repeat_action(5, || { + count += 1; + }); + assert_eq!(count, 5); + } + + #[test] + fn test_compose() { + let double = |x: i32| x * 2; + let add_ten = |x: i32| x + 10; + + let composed = DeepMindBuiltins::compose(double, add_ten); + assert_eq!(composed(5), 30); // double(add_ten(5)) = double(15) = 30 + } + + #[test] + fn test_pipe() { + let double = |x: i32| x * 2; + let add_ten = |x: i32| x + 10; + + let piped = DeepMindBuiltins::pipe(double, add_ten); + assert_eq!(piped(5), 20); // add_ten(double(5)) = add_ten(10) = 20 + } + + #[test] + fn test_repeat_until() { + use std::cell::RefCell; + let count = RefCell::new(0); + DeepMindBuiltins::repeat_until( + || { + *count.borrow_mut() += 1; + }, + || *count.borrow() >= 5, + ); + assert_eq!(*count.borrow(), 5); + } + + #[test] + fn test_repeat_while() { + use std::cell::RefCell; + let n = RefCell::new(3); + DeepMindBuiltins::repeat_while( + || *n.borrow() > 0, + || { + *n.borrow_mut() -= 1; + }, + ); + assert_eq!(*n.borrow(), 0); + } + + #[test] + fn test_ensure_awakening() { + let mut cleanup_called = false; + DeepMindBuiltins::ensure_awakening( + || { /* main action */ }, + || { + cleanup_called = true; + }, + ); + assert!(cleanup_called); + } +} diff --git a/hypnoscript-runtime/src/file_builtins.rs b/hypnoscript-runtime/src/file_builtins.rs new file mode 100644 index 0000000..2a2939a --- /dev/null +++ b/hypnoscript-runtime/src/file_builtins.rs @@ -0,0 +1,186 @@ +use std::fs; +use std::io::{self, Write}; +use std::path::Path; + +/// File I/O builtin functions +pub struct FileBuiltins; + +impl FileBuiltins { + /// Ensure the parent directory of a path exists + fn ensure_parent_dir(path: &Path) -> io::Result<()> { + if let Some(parent) = path.parent() { + if !parent.as_os_str().is_empty() { + fs::create_dir_all(parent)?; + } + } + Ok(()) + } + + /// Read entire file as string + pub fn read_file(path: &str) -> io::Result { + fs::read_to_string(path) + } + + /// Write string to file + pub fn write_file(path: &str, content: &str) -> io::Result<()> { + let path_ref = Path::new(path); + Self::ensure_parent_dir(path_ref)?; + fs::write(path_ref, content) + } + + /// Append string to file + pub fn append_file(path: &str, content: &str) -> io::Result<()> { + let path_ref = Path::new(path); + Self::ensure_parent_dir(path_ref)?; + + let mut file = fs::OpenOptions::new() + .create(true) + .append(true) + .open(path_ref)?; + file.write_all(content.as_bytes()) + } + + /// Check if file exists + pub fn file_exists(path: &str) -> bool { + Path::new(path).exists() + } + + /// Check if path is file + pub fn is_file(path: &str) -> bool { + Path::new(path).is_file() + } + + /// Check if path is directory + pub fn is_directory(path: &str) -> bool { + Path::new(path).is_dir() + } + + /// Delete file + pub fn delete_file(path: &str) -> io::Result<()> { + fs::remove_file(path) + } + + /// Create directory + pub fn create_directory(path: &str) -> io::Result<()> { + fs::create_dir_all(path) + } + + /// List files in directory + pub fn list_directory(path: &str) -> io::Result> { + let mut files = Vec::new(); + for entry in fs::read_dir(path)? { + let entry = entry?; + if let Some(name) = entry.file_name().to_str() { + files.push(name.to_string()); + } + } + Ok(files) + } + + /// Get file size in bytes + pub fn get_file_size(path: &str) -> io::Result { + fs::metadata(path).map(|m| m.len()) + } + + /// Copy file + pub fn copy_file(from: &str, to: &str) -> io::Result { + fs::copy(from, to) + } + + /// Rename/move file + pub fn rename_file(from: &str, to: &str) -> io::Result<()> { + fs::rename(from, to) + } + + /// Get file extension + pub fn get_file_extension(path: &str) -> Option { + Path::new(path) + .extension() + .and_then(|s| s.to_str()) + .map(|s| s.to_string()) + } + + /// Get file name without extension + pub fn get_file_name(path: &str) -> Option { + Path::new(path) + .file_stem() + .and_then(|s| s.to_str()) + .map(|s| s.to_string()) + } + + /// Get parent directory + pub fn get_parent_directory(path: &str) -> Option { + Path::new(path) + .parent() + .and_then(|p| p.to_str()) + .map(|s| s.to_string()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::env; + use std::fs; + use std::path::PathBuf; + + fn temp_file_path(name: &str) -> PathBuf { + let mut path = env::temp_dir(); + path.push(name); + path + } + + fn unique_test_file() -> PathBuf { + let timestamp = std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap() + .as_nanos(); + temp_file_path(&format!("hypnoscript_test_{}.txt", timestamp)) + } + + #[test] + fn test_file_operations() { + let test_file = unique_test_file(); + let test_file_str = test_file.to_string_lossy().into_owned(); + + // Write file + assert!(FileBuiltins::write_file(&test_file_str, "Hello, World!").is_ok()); + + // Check exists + assert!(FileBuiltins::file_exists(&test_file_str)); + assert!(FileBuiltins::is_file(&test_file_str)); + + // Read file + let content = FileBuiltins::read_file(&test_file_str).unwrap(); + assert_eq!(content, "Hello, World!"); + + // Append + assert!(FileBuiltins::append_file(&test_file_str, " More text.").is_ok()); + let content = FileBuiltins::read_file(&test_file_str).unwrap(); + assert_eq!(content, "Hello, World! More text."); + + // Get size + let size = FileBuiltins::get_file_size(&test_file_str).unwrap(); + assert!(size > 0); + + // Delete + assert!(FileBuiltins::delete_file(&test_file_str).is_ok()); + assert!(!FileBuiltins::file_exists(&test_file_str)); + + // Clean up in case delete failed silently on certain platforms + let _ = fs::remove_file(&test_file); + } + + #[test] + fn test_path_operations() { + assert_eq!( + FileBuiltins::get_file_extension("test.txt"), + Some("txt".to_string()) + ); + assert_eq!( + FileBuiltins::get_file_name("test.txt"), + Some("test".to_string()) + ); + assert_eq!(FileBuiltins::get_file_extension("test"), None); + } +} diff --git a/hypnoscript-runtime/src/hashing_builtins.rs b/hypnoscript-runtime/src/hashing_builtins.rs new file mode 100644 index 0000000..9a14531 --- /dev/null +++ b/hypnoscript-runtime/src/hashing_builtins.rs @@ -0,0 +1,144 @@ +use std::collections::hash_map::DefaultHasher; +use std::hash::{Hash, Hasher}; + +/// Hashing and utility builtin functions +pub struct HashingBuiltins; + +impl HashingBuiltins { + /// Calculate simple hash of string + pub fn hash_string(s: &str) -> u64 { + let mut hasher = DefaultHasher::new(); + s.hash(&mut hasher); + hasher.finish() + } + + /// Calculate simple hash of number + pub fn hash_number(n: f64) -> u64 { + let mut hasher = DefaultHasher::new(); + n.to_bits().hash(&mut hasher); + hasher.finish() + } + + /// Generate a simple pseudo-random number (not cryptographically secure) + pub fn simple_random(seed: u64) -> u64 { + // Simple LCG (Linear Congruential Generator) + const A: u64 = 6364136223846793005; + const C: u64 = 1442695040888963407; + seed.wrapping_mul(A).wrapping_add(C) + } + + /// Check if two strings are anagrams + pub fn are_anagrams(s1: &str, s2: &str) -> bool { + let mut chars1: Vec = s1.chars().collect(); + let mut chars2: Vec = s2.chars().collect(); + chars1.sort_unstable(); + chars2.sort_unstable(); + chars1 == chars2 + } + + /// Check if string is palindrome + pub fn is_palindrome(s: &str) -> bool { + let clean: String = s.chars().filter(|c| c.is_alphanumeric()).collect(); + let lower = clean.to_lowercase(); + lower == lower.chars().rev().collect::() + } + + /// Count occurrences of substring + pub fn count_occurrences(text: &str, pattern: &str) -> usize { + if pattern.is_empty() { + return 0; + } + text.matches(pattern).count() + } + + /// Remove duplicates from string + pub fn remove_duplicates(s: &str) -> String { + use std::collections::HashSet; + let mut seen = HashSet::new(); + s.chars().filter(|c| seen.insert(*c)).collect() + } + + /// Get unique characters in string + pub fn unique_characters(s: &str) -> String { + use std::collections::HashSet; + let unique: HashSet = s.chars().collect(); + unique.into_iter().collect() + } + + /// Reverse words in string + pub fn reverse_words(s: &str) -> String { + s.split_whitespace().rev().collect::>().join(" ") + } + + /// Title case (capitalize first letter of each word) + pub fn title_case(s: &str) -> String { + s.split_whitespace() + .map(|word| { + let mut chars = word.chars(); + match chars.next() { + None => String::new(), + Some(first) => first.to_uppercase().chain(chars).collect(), + } + }) + .collect::>() + .join(" ") + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_hash_string() { + let hash1 = HashingBuiltins::hash_string("hello"); + let hash2 = HashingBuiltins::hash_string("hello"); + let hash3 = HashingBuiltins::hash_string("world"); + + assert_eq!(hash1, hash2); + assert_ne!(hash1, hash3); + } + + #[test] + fn test_are_anagrams() { + assert!(HashingBuiltins::are_anagrams("listen", "silent")); + assert!(HashingBuiltins::are_anagrams("evil", "vile")); + assert!(!HashingBuiltins::are_anagrams("hello", "world")); + } + + #[test] + fn test_is_palindrome() { + assert!(HashingBuiltins::is_palindrome("racecar")); + assert!(HashingBuiltins::is_palindrome( + "A man a plan a canal Panama" + )); + assert!(!HashingBuiltins::is_palindrome("hello")); + } + + #[test] + fn test_count_occurrences() { + assert_eq!( + HashingBuiltins::count_occurrences("hello world hello", "hello"), + 2 + ); + assert_eq!(HashingBuiltins::count_occurrences("abcabc", "abc"), 2); + } + + #[test] + fn test_reverse_words() { + assert_eq!(HashingBuiltins::reverse_words("hello world"), "world hello"); + assert_eq!( + HashingBuiltins::reverse_words("one two three"), + "three two one" + ); + } + + #[test] + fn test_title_case() { + assert_eq!(HashingBuiltins::title_case("hello world"), "Hello World"); + assert_eq!( + HashingBuiltins::title_case("the quick brown fox"), + "The Quick Brown Fox" + ); + } +} diff --git a/hypnoscript-runtime/src/lib.rs b/hypnoscript-runtime/src/lib.rs new file mode 100644 index 0000000..bc201da --- /dev/null +++ b/hypnoscript-runtime/src/lib.rs @@ -0,0 +1,28 @@ +//! HypnoScript Runtime Library +//! +//! This module provides the runtime environment and builtin functions for HypnoScript. + +pub mod array_builtins; +pub mod core_builtins; +pub mod deepmind_builtins; +pub mod file_builtins; +pub mod hashing_builtins; +pub mod math_builtins; +pub mod statistics_builtins; +pub mod string_builtins; +pub mod system_builtins; +pub mod time_builtins; +pub mod validation_builtins; + +// Re-export builtin modules +pub use array_builtins::ArrayBuiltins; +pub use core_builtins::CoreBuiltins; +pub use deepmind_builtins::DeepMindBuiltins; +pub use file_builtins::FileBuiltins; +pub use hashing_builtins::HashingBuiltins; +pub use math_builtins::MathBuiltins; +pub use statistics_builtins::StatisticsBuiltins; +pub use string_builtins::StringBuiltins; +pub use system_builtins::SystemBuiltins; +pub use time_builtins::TimeBuiltins; +pub use validation_builtins::ValidationBuiltins; diff --git a/hypnoscript-runtime/src/math_builtins.rs b/hypnoscript-runtime/src/math_builtins.rs new file mode 100644 index 0000000..80e73f7 --- /dev/null +++ b/hypnoscript-runtime/src/math_builtins.rs @@ -0,0 +1,179 @@ +use std::f64; + +/// Mathematical builtin functions +pub struct MathBuiltins; + +impl MathBuiltins { + /// Sine function + pub fn sin(x: f64) -> f64 { + x.sin() + } + + /// Cosine function + pub fn cos(x: f64) -> f64 { + x.cos() + } + + /// Tangent function + pub fn tan(x: f64) -> f64 { + x.tan() + } + + /// Square root + pub fn sqrt(x: f64) -> f64 { + x.sqrt() + } + + /// Power function + pub fn pow(base: f64, exponent: f64) -> f64 { + base.powf(exponent) + } + + /// Natural logarithm + pub fn log(x: f64) -> f64 { + x.ln() + } + + /// Base-10 logarithm + pub fn log10(x: f64) -> f64 { + x.log10() + } + + /// Absolute value + pub fn abs(x: f64) -> f64 { + x.abs() + } + + /// Floor function + pub fn floor(x: f64) -> f64 { + x.floor() + } + + /// Ceiling function + pub fn ceil(x: f64) -> f64 { + x.ceil() + } + + /// Round function + pub fn round(x: f64) -> f64 { + x.round() + } + + /// Minimum of two values + pub fn min(a: f64, b: f64) -> f64 { + a.min(b) + } + + /// Maximum of two values + pub fn max(a: f64, b: f64) -> f64 { + a.max(b) + } + + /// Factorial + pub fn factorial(n: i64) -> i64 { + if n <= 1 { + 1 + } else { + (2..=n).product() + } + } + + /// Greatest Common Divisor + pub fn gcd(mut a: i64, mut b: i64) -> i64 { + while b != 0 { + let temp = b; + b = a % b; + a = temp; + } + a.abs() + } + + /// Least Common Multiple + pub fn lcm(a: i64, b: i64) -> i64 { + if a == 0 || b == 0 { + 0 + } else { + (a * b).abs() / Self::gcd(a, b) + } + } + + /// Check if number is prime + pub fn is_prime(n: i64) -> bool { + if n <= 1 { + return false; + } + if n <= 3 { + return true; + } + if n % 2 == 0 || n % 3 == 0 { + return false; + } + let mut i = 5; + while i * i <= n { + if n % i == 0 || n % (i + 2) == 0 { + return false; + } + i += 6; + } + true + } + + /// Fibonacci number + pub fn fibonacci(n: i64) -> i64 { + if n <= 1 { + n + } else { + let mut a = 0; + let mut b = 1; + for _ in 2..=n { + let temp = a + b; + a = b; + b = temp; + } + b + } + } + + /// Clamp value between min and max + pub fn clamp(value: f64, min: f64, max: f64) -> f64 { + if value < min { + min + } else if value > max { + max + } else { + value + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_factorial() { + assert_eq!(MathBuiltins::factorial(5), 120); + assert_eq!(MathBuiltins::factorial(0), 1); + } + + #[test] + fn test_gcd() { + assert_eq!(MathBuiltins::gcd(48, 18), 6); + assert_eq!(MathBuiltins::gcd(100, 50), 50); + } + + #[test] + fn test_is_prime() { + assert!(MathBuiltins::is_prime(7)); + assert!(MathBuiltins::is_prime(13)); + assert!(!MathBuiltins::is_prime(4)); + assert!(!MathBuiltins::is_prime(1)); + } + + #[test] + fn test_fibonacci() { + assert_eq!(MathBuiltins::fibonacci(0), 0); + assert_eq!(MathBuiltins::fibonacci(1), 1); + assert_eq!(MathBuiltins::fibonacci(10), 55); + } +} diff --git a/hypnoscript-runtime/src/statistics_builtins.rs b/hypnoscript-runtime/src/statistics_builtins.rs new file mode 100644 index 0000000..8bf79ea --- /dev/null +++ b/hypnoscript-runtime/src/statistics_builtins.rs @@ -0,0 +1,184 @@ +/// Statistics builtin functions +pub struct StatisticsBuiltins; + +impl StatisticsBuiltins { + /// Calculate mean (average) of numbers + pub fn calculate_mean(numbers: &[f64]) -> f64 { + if numbers.is_empty() { + return 0.0; + } + numbers.iter().sum::() / numbers.len() as f64 + } + + /// Calculate median of numbers + pub fn calculate_median(numbers: &[f64]) -> f64 { + if numbers.is_empty() { + return 0.0; + } + let mut sorted = numbers.to_vec(); + sorted.sort_by(|a, b| a.partial_cmp(b).unwrap()); + let len = sorted.len(); + if len.is_multiple_of(2) { + (sorted[len / 2 - 1] + sorted[len / 2]) / 2.0 + } else { + sorted[len / 2] + } + } + + /// Calculate mode (most frequent value) + pub fn calculate_mode(numbers: &[f64]) -> f64 { + if numbers.is_empty() { + return 0.0; + } + + use std::collections::HashMap; + let mut counts = HashMap::new(); + for &n in numbers { + *counts.entry(n.to_bits()).or_insert(0) += 1; + } + + counts + .iter() + .max_by_key(|(_, &count)| count) + .map(|(bits, _)| f64::from_bits(*bits)) + .unwrap_or(0.0) + } + + /// Calculate standard deviation + pub fn calculate_standard_deviation(numbers: &[f64]) -> f64 { + if numbers.len() < 2 { + return 0.0; + } + let mean = Self::calculate_mean(numbers); + let variance = + numbers.iter().map(|&x| (x - mean).powi(2)).sum::() / (numbers.len() - 1) as f64; + variance.sqrt() + } + + /// Calculate variance + pub fn calculate_variance(numbers: &[f64]) -> f64 { + if numbers.len() < 2 { + return 0.0; + } + let mean = Self::calculate_mean(numbers); + numbers.iter().map(|&x| (x - mean).powi(2)).sum::() / (numbers.len() - 1) as f64 + } + + /// Calculate range (max - min) + pub fn calculate_range(numbers: &[f64]) -> f64 { + if numbers.is_empty() { + return 0.0; + } + let min = numbers.iter().fold(f64::INFINITY, |a, &b| a.min(b)); + let max = numbers.iter().fold(f64::NEG_INFINITY, |a, &b| a.max(b)); + max - min + } + + /// Calculate percentile + pub fn calculate_percentile(numbers: &[f64], percentile: f64) -> f64 { + if numbers.is_empty() || !(0.0..=100.0).contains(&percentile) { + return 0.0; + } + let mut sorted = numbers.to_vec(); + sorted.sort_by(|a, b| a.partial_cmp(b).unwrap()); + let index = (percentile / 100.0 * (sorted.len() - 1) as f64).round() as usize; + sorted[index] + } + + /// Calculate correlation coefficient between two arrays + pub fn calculate_correlation(x: &[f64], y: &[f64]) -> f64 { + if x.len() != y.len() || x.is_empty() { + return 0.0; + } + + let mean_x = Self::calculate_mean(x); + let mean_y = Self::calculate_mean(y); + + let numerator: f64 = x + .iter() + .zip(y.iter()) + .map(|(&xi, &yi)| (xi - mean_x) * (yi - mean_y)) + .sum(); + + let denom_x: f64 = x.iter().map(|&xi| (xi - mean_x).powi(2)).sum(); + let denom_y: f64 = y.iter().map(|&yi| (yi - mean_y).powi(2)).sum(); + + if denom_x == 0.0 || denom_y == 0.0 { + return 0.0; + } + + numerator / (denom_x * denom_y).sqrt() + } + + /// Simple linear regression (returns slope and intercept) + pub fn linear_regression(x: &[f64], y: &[f64]) -> (f64, f64) { + if x.len() != y.len() || x.is_empty() { + return (0.0, 0.0); + } + + let mean_x = Self::calculate_mean(x); + let mean_y = Self::calculate_mean(y); + + let numerator: f64 = x + .iter() + .zip(y.iter()) + .map(|(&xi, &yi)| (xi - mean_x) * (yi - mean_y)) + .sum(); + + let denominator: f64 = x.iter().map(|&xi| (xi - mean_x).powi(2)).sum(); + + if denominator == 0.0 { + return (0.0, mean_y); + } + + let slope = numerator / denominator; + let intercept = mean_y - slope * mean_x; + + (slope, intercept) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_calculate_mean() { + assert_eq!( + StatisticsBuiltins::calculate_mean(&[1.0, 2.0, 3.0, 4.0, 5.0]), + 3.0 + ); + assert_eq!( + StatisticsBuiltins::calculate_mean(&[10.0, 20.0, 30.0]), + 20.0 + ); + } + + #[test] + fn test_calculate_median() { + assert_eq!( + StatisticsBuiltins::calculate_median(&[1.0, 2.0, 3.0, 4.0, 5.0]), + 3.0 + ); + assert_eq!( + StatisticsBuiltins::calculate_median(&[1.0, 2.0, 3.0, 4.0]), + 2.5 + ); + } + + #[test] + fn test_calculate_standard_deviation() { + let data = vec![2.0, 4.0, 4.0, 4.0, 5.0, 5.0, 7.0, 9.0]; + let sd = StatisticsBuiltins::calculate_standard_deviation(&data); + assert!((sd - 2.138).abs() < 0.01); // Approximately 2.138 + } + + #[test] + fn test_calculate_range() { + assert_eq!( + StatisticsBuiltins::calculate_range(&[1.0, 2.0, 3.0, 4.0, 5.0]), + 4.0 + ); + assert_eq!(StatisticsBuiltins::calculate_range(&[10.0, 100.0]), 90.0); + } +} diff --git a/hypnoscript-runtime/src/string_builtins.rs b/hypnoscript-runtime/src/string_builtins.rs new file mode 100644 index 0000000..ce39b26 --- /dev/null +++ b/hypnoscript-runtime/src/string_builtins.rs @@ -0,0 +1,135 @@ +/// String builtin functions +pub struct StringBuiltins; + +impl StringBuiltins { + /// Get string length + pub fn length(s: &str) -> usize { + s.len() + } + + /// Convert to uppercase + pub fn to_upper(s: &str) -> String { + s.to_uppercase() + } + + /// Convert to lowercase + pub fn to_lower(s: &str) -> String { + s.to_lowercase() + } + + /// Trim whitespace + pub fn trim(s: &str) -> String { + s.trim().to_string() + } + + /// Find index of substring + pub fn index_of(s: &str, pattern: &str) -> i64 { + s.find(pattern).map(|i| i as i64).unwrap_or(-1) + } + + /// Replace substring + pub fn replace(s: &str, from: &str, to: &str) -> String { + s.replace(from, to) + } + + /// Reverse string + pub fn reverse(s: &str) -> String { + s.chars().rev().collect() + } + + /// Capitalize first letter + pub fn capitalize(s: &str) -> String { + let mut chars = s.chars(); + match chars.next() { + None => String::new(), + Some(first) => first.to_uppercase().collect::() + chars.as_str(), + } + } + + /// Check if string starts with prefix + pub fn starts_with(s: &str, prefix: &str) -> bool { + s.starts_with(prefix) + } + + /// Check if string ends with suffix + pub fn ends_with(s: &str, suffix: &str) -> bool { + s.ends_with(suffix) + } + + /// Check if string contains substring + pub fn contains(s: &str, pattern: &str) -> bool { + s.contains(pattern) + } + + /// Split string by delimiter + pub fn split(s: &str, delimiter: &str) -> Vec { + s.split(delimiter).map(|s| s.to_string()).collect() + } + + /// Substring from start to end + pub fn substring(s: &str, start: usize, end: usize) -> String { + let chars: Vec = s.chars().collect(); + let start = start.min(chars.len()); + let end = end.min(chars.len()); + if start >= end { + String::new() + } else { + chars[start..end].iter().collect() + } + } + + /// Repeat string n times + pub fn repeat(s: &str, times: usize) -> String { + s.repeat(times) + } + + /// Pad left with character + pub fn pad_left(s: &str, total_width: usize, pad_char: char) -> String { + let padding = total_width.saturating_sub(s.len()); + format!("{}{}", pad_char.to_string().repeat(padding), s) + } + + /// Pad right with character + pub fn pad_right(s: &str, total_width: usize, pad_char: char) -> String { + let padding = total_width.saturating_sub(s.len()); + format!("{}{}", s, pad_char.to_string().repeat(padding)) + } + + /// Check if string is empty + pub fn is_empty(s: &str) -> bool { + s.is_empty() + } + + /// Check if string is whitespace + pub fn is_whitespace(s: &str) -> bool { + s.chars().all(char::is_whitespace) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_length() { + assert_eq!(StringBuiltins::length("hello"), 5); + assert_eq!(StringBuiltins::length(""), 0); + } + + #[test] + fn test_reverse() { + assert_eq!(StringBuiltins::reverse("hello"), "olleh"); + } + + #[test] + fn test_capitalize() { + assert_eq!(StringBuiltins::capitalize("hello"), "Hello"); + assert_eq!(StringBuiltins::capitalize(""), ""); + } + + #[test] + fn test_index_of() { + assert_eq!(StringBuiltins::index_of("hello world", "world"), 6); + assert_eq!(StringBuiltins::index_of("hello", "xyz"), -1); + } +} diff --git a/hypnoscript-runtime/src/system_builtins.rs b/hypnoscript-runtime/src/system_builtins.rs new file mode 100644 index 0000000..f082ad3 --- /dev/null +++ b/hypnoscript-runtime/src/system_builtins.rs @@ -0,0 +1,108 @@ +use std::env; + +/// System information builtin functions +pub struct SystemBuiltins; + +impl SystemBuiltins { + /// Get current directory + pub fn get_current_directory() -> String { + env::current_dir() + .ok() + .and_then(|p| p.to_str().map(|s| s.to_string())) + .unwrap_or_else(|| ".".to_string()) + } + + /// Get environment variable + pub fn get_env_var(name: &str) -> Option { + env::var(name).ok() + } + + /// Set environment variable + pub fn set_env_var(name: &str, value: &str) { + env::set_var(name, value); + } + + /// Get operating system + pub fn get_operating_system() -> String { + env::consts::OS.to_string() + } + + /// Get architecture + pub fn get_architecture() -> String { + env::consts::ARCH.to_string() + } + + /// Get number of CPU cores + pub fn get_cpu_count() -> usize { + num_cpus::get() + } + + /// Get hostname + pub fn get_hostname() -> String { + hostname::get() + .ok() + .and_then(|h| h.into_string().ok()) + .unwrap_or_else(|| "unknown".to_string()) + } + + /// Get username + pub fn get_username() -> String { + env::var("USER") + .or_else(|_| env::var("USERNAME")) + .unwrap_or_else(|_| "unknown".to_string()) + } + + /// Get home directory + pub fn get_home_directory() -> String { + env::var("HOME") + .or_else(|_| env::var("USERPROFILE")) + .unwrap_or_else(|_| ".".to_string()) + } + + /// Get temporary directory + pub fn get_temp_directory() -> String { + env::temp_dir() + .to_str() + .map(|s| s.to_string()) + .unwrap_or_else(|| "/tmp".to_string()) + } + + /// Get program arguments + pub fn get_args() -> Vec { + env::args().collect() + } + + /// Exit program with code + pub fn exit(code: i32) -> ! { + std::process::exit(code) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_get_operating_system() { + let os = SystemBuiltins::get_operating_system(); + assert!(!os.is_empty()); + } + + #[test] + fn test_get_architecture() { + let arch = SystemBuiltins::get_architecture(); + assert!(!arch.is_empty()); + } + + #[test] + fn test_get_cpu_count() { + let count = SystemBuiltins::get_cpu_count(); + assert!(count > 0); + } + + #[test] + fn test_current_directory() { + let dir = SystemBuiltins::get_current_directory(); + assert!(!dir.is_empty()); + } +} diff --git a/hypnoscript-runtime/src/time_builtins.rs b/hypnoscript-runtime/src/time_builtins.rs new file mode 100644 index 0000000..36fcf8f --- /dev/null +++ b/hypnoscript-runtime/src/time_builtins.rs @@ -0,0 +1,109 @@ +use chrono::{Datelike, Local, NaiveDate, Timelike}; + +/// Time and date builtin functions +pub struct TimeBuiltins; + +impl TimeBuiltins { + /// Get current Unix timestamp + pub fn get_current_time() -> i64 { + Local::now().timestamp() + } + + /// Get current date as string + pub fn get_current_date() -> String { + Local::now().format("%Y-%m-%d").to_string() + } + + /// Get current time as string + pub fn get_current_time_string() -> String { + Local::now().format("%H:%M:%S").to_string() + } + + /// Get current date and time as string + pub fn get_current_date_time() -> String { + Local::now().format("%Y-%m-%d %H:%M:%S").to_string() + } + + /// Format current date time with custom format + pub fn format_date_time(format: &str) -> String { + Local::now().format(format).to_string() + } + + /// Get day of week (0=Sunday, 6=Saturday) + pub fn get_day_of_week() -> u32 { + Local::now().weekday().num_days_from_sunday() + } + + /// Get day of year + pub fn get_day_of_year() -> u32 { + Local::now().ordinal() + } + + /// Check if year is leap year + pub fn is_leap_year(year: i32) -> bool { + NaiveDate::from_ymd_opt(year, 2, 29).is_some() + } + + /// Get number of days in month + pub fn get_days_in_month(year: i32, month: u32) -> Option { + NaiveDate::from_ymd_opt(year, month, 1).and_then(|date| { + if month == 12 { + NaiveDate::from_ymd_opt(year + 1, 1, 1) + } else { + NaiveDate::from_ymd_opt(year, month + 1, 1) + } + .map(|next_month| (next_month - date).num_days() as u32) + }) + } + + /// Get current year + pub fn get_year() -> i32 { + Local::now().year() + } + + /// Get current month + pub fn get_month() -> u32 { + Local::now().month() + } + + /// Get current day + pub fn get_day() -> u32 { + Local::now().day() + } + + /// Get current hour + pub fn get_hour() -> u32 { + Local::now().hour() + } + + /// Get current minute + pub fn get_minute() -> u32 { + Local::now().minute() + } + + /// Get current second + pub fn get_second() -> u32 { + Local::now().second() + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_is_leap_year() { + assert!(TimeBuiltins::is_leap_year(2020)); + assert!(!TimeBuiltins::is_leap_year(2021)); + assert!(TimeBuiltins::is_leap_year(2000)); + assert!(!TimeBuiltins::is_leap_year(1900)); + } + + #[test] + fn test_days_in_month() { + assert_eq!(TimeBuiltins::get_days_in_month(2020, 2), Some(29)); // Leap year + assert_eq!(TimeBuiltins::get_days_in_month(2021, 2), Some(28)); // Not leap year + assert_eq!(TimeBuiltins::get_days_in_month(2021, 1), Some(31)); + assert_eq!(TimeBuiltins::get_days_in_month(2021, 4), Some(30)); + } +} diff --git a/hypnoscript-runtime/src/validation_builtins.rs b/hypnoscript-runtime/src/validation_builtins.rs new file mode 100644 index 0000000..73e36f4 --- /dev/null +++ b/hypnoscript-runtime/src/validation_builtins.rs @@ -0,0 +1,112 @@ +use regex::Regex; +use std::sync::OnceLock; + +/// Validation builtin functions +pub struct ValidationBuiltins; + +static EMAIL_REGEX: OnceLock = OnceLock::new(); +static URL_REGEX: OnceLock = OnceLock::new(); +static PHONE_REGEX: OnceLock = OnceLock::new(); + +impl ValidationBuiltins { + /// Check if string is valid email + pub fn is_valid_email(email: &str) -> bool { + let regex = EMAIL_REGEX.get_or_init(|| { + Regex::new(r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$").unwrap() + }); + regex.is_match(email) + } + + /// Check if string is valid URL + pub fn is_valid_url(url: &str) -> bool { + let regex = URL_REGEX.get_or_init(|| Regex::new(r"^https?://[^\s/$.?#].[^\s]*$").unwrap()); + regex.is_match(url) + } + + /// Check if string is valid phone number (simple format) + pub fn is_valid_phone_number(phone: &str) -> bool { + let regex = PHONE_REGEX.get_or_init(|| Regex::new(r"^\+?[1-9]\d{1,14}$").unwrap()); + regex.is_match(&phone.replace(&['-', ' ', '(', ')'][..], "")) + } + + /// Check if string is alphanumeric + pub fn is_alphanumeric(s: &str) -> bool { + !s.is_empty() && s.chars().all(|c| c.is_alphanumeric()) + } + + /// Check if string is alphabetic + pub fn is_alphabetic(s: &str) -> bool { + !s.is_empty() && s.chars().all(|c| c.is_alphabetic()) + } + + /// Check if string is numeric + pub fn is_numeric(s: &str) -> bool { + !s.is_empty() && s.chars().all(|c| c.is_numeric()) + } + + /// Check if string is lowercase + pub fn is_lowercase(s: &str) -> bool { + !s.is_empty() + && s.chars() + .filter(|c| c.is_alphabetic()) + .all(|c| c.is_lowercase()) + } + + /// Check if string is uppercase + pub fn is_uppercase(s: &str) -> bool { + !s.is_empty() + && s.chars() + .filter(|c| c.is_alphabetic()) + .all(|c| c.is_uppercase()) + } + + /// Check if number is in range + pub fn is_in_range(value: f64, min: f64, max: f64) -> bool { + value >= min && value <= max + } + + /// Check if string matches pattern (regex) + pub fn matches_pattern(text: &str, pattern: &str) -> bool { + Regex::new(pattern) + .map(|r| r.is_match(text)) + .unwrap_or(false) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_is_valid_email() { + assert!(ValidationBuiltins::is_valid_email("test@example.com")); + assert!(ValidationBuiltins::is_valid_email("user.name@domain.co.uk")); + assert!(!ValidationBuiltins::is_valid_email("invalid.email")); + assert!(!ValidationBuiltins::is_valid_email("@example.com")); + } + + #[test] + fn test_is_valid_url() { + assert!(ValidationBuiltins::is_valid_url("http://example.com")); + assert!(ValidationBuiltins::is_valid_url( + "https://www.example.com/path" + )); + assert!(!ValidationBuiltins::is_valid_url("not a url")); + assert!(!ValidationBuiltins::is_valid_url("ftp://example.com")); + } + + #[test] + fn test_is_alphanumeric() { + assert!(ValidationBuiltins::is_alphanumeric("abc123")); + assert!(ValidationBuiltins::is_alphanumeric("ABC")); + assert!(!ValidationBuiltins::is_alphanumeric("abc 123")); + assert!(!ValidationBuiltins::is_alphanumeric("")); + } + + #[test] + fn test_is_in_range() { + assert!(ValidationBuiltins::is_in_range(5.0, 1.0, 10.0)); + assert!(!ValidationBuiltins::is_in_range(15.0, 1.0, 10.0)); + assert!(ValidationBuiltins::is_in_range(1.0, 1.0, 10.0)); + } +} diff --git a/medium_test.hyp b/hypnoscript-tests/medium_test.hyp similarity index 85% rename from medium_test.hyp rename to hypnoscript-tests/medium_test.hyp index 579767d..75d2aff 100644 --- a/medium_test.hyp +++ b/hypnoscript-tests/medium_test.hyp @@ -4,14 +4,14 @@ Focus { drift(100); } - // ===== BASIC OPERATIONS ===== + // ===== BASIC OPERATIONS =====; observe "=== Basic Operations ==="; induce x = 10; induce y = 20; induce result = x + y; observe "Basic math: " + result; - // ===== STRING OPERATIONS ===== + // ===== STRING OPERATIONS =====; observe "=== String Operations ==="; induce text = "Hello HypnoScript Runtime"; induce length = StringLength(text); @@ -19,7 +19,7 @@ Focus { induce upper = StringToUpper(text); observe "Uppercase: " + upper; - // ===== ARRAY OPERATIONS ===== + // ===== ARRAY OPERATIONS =====; observe "=== Array Operations ==="; induce numbers = [1, 2, 3, 4, 5]; induce sum = ArraySum(numbers); @@ -27,40 +27,40 @@ Focus { observe "Array sum: " + sum; observe "Array count: " + count; - // ===== VALIDATION FUNCTIONS ===== + // ===== VALIDATION FUNCTIONS =====; observe "=== Validation Functions ==="; induce email = "test@example.com"; induce url = "https://www.example.com"; observe "Email valid: " + IsValidEmail(email); observe "URL valid: " + IsValidUrl(url); - // ===== FORMATTING FUNCTIONS ===== + // ===== FORMATTING FUNCTIONS =====; observe "=== Formatting Functions ==="; induce amount = 99.99; induce percentage = 75.5; observe "Currency: " + FormatCurrency(amount, "EUR"); observe "Percentage: " + FormatPercentage(percentage); - // ===== MATHEMATICAL FUNCTIONS ===== + // ===== MATHEMATICAL FUNCTIONS =====; observe "=== Mathematical Functions ==="; observe "Factorial(5): " + Factorial(5); observe "GCD(48, 18): " + GCD(48, 18); observe "LCM(12, 18): " + LCM(12, 18); - // ===== FILE OPERATIONS ===== + // ===== FILE OPERATIONS =====; observe "=== File Operations ==="; induce content = "Test file created by HypnoScript Runtime v1.0.0"; WriteFile("medium_test_output.txt", content); induce readContent = ReadFile("medium_test_output.txt"); observe "File content: " + readContent; - // ===== JSON OPERATIONS ===== + // ===== JSON OPERATIONS =====; observe "=== JSON Operations ==="; induce data = CreateRecord(["name", "version"], ["HypnoScript", "1.0.0"]); induce jsonString = ToJson(data); observe "JSON: " + jsonString; - // ===== PERFORMANCE MONITORING ===== + // ===== PERFORMANCE MONITORING =====; observe "=== Performance Monitoring ==="; induce metrics = GetPerformanceMetrics(); observe "Performance metrics available: " + (metrics != null); diff --git a/simple_test.hyp b/hypnoscript-tests/simple_test.hyp similarity index 100% rename from simple_test.hyp rename to hypnoscript-tests/simple_test.hyp diff --git a/test.hyp b/hypnoscript-tests/test.hyp similarity index 92% rename from test.hyp rename to hypnoscript-tests/test.hyp index f744367..454ad4a 100644 --- a/test.hyp +++ b/hypnoscript-tests/test.hyp @@ -7,7 +7,7 @@ Focus { drift(500); } - // ===== GRUNDLEGENDE FEATURES ===== + // ===== GRUNDLEGENDE FEATURES =====; // Variablendeklarationen mit verschiedenen Typen induce greeting: string = "Hello from HypnoScript!"; @@ -20,7 +20,7 @@ Focus { induce y: number = 5; induce result: number = x * y + 15; - // ===== ERWEITERTE DATENSTRUKTUREN ===== + // ===== ERWEITERTE DATENSTRUKTUREN =====; // Tranceify-Struktur definieren tranceify HypnoRecord { @@ -42,7 +42,7 @@ Focus { observe "Record Name: " + record.name; observe "Trance Level: " + record.tranceLevel; - // ===== OBJEKTORIENTIERUNG ===== + // ===== OBJEKTORIENTIERUNG =====; // Session (Klasse) definieren session Person { @@ -83,7 +83,7 @@ Focus { person1.enterTrance(); person1.greet(); - // ===== KONTROLLSTRUKTUREN ===== + // ===== KONTROLLSTRUKTUREN =====; // If-Else mit hypnotischen Operatoren if (counter youAreFeelingVerySleepy 0) deepFocus { @@ -111,7 +111,7 @@ Focus { observe "Loop iteration: " + i; } - // ===== FUNKTIONEN ===== + // ===== FUNKTIONEN =====; // Funktion mit Rückgabewert suggestion add(a: number, b: number): number { @@ -142,13 +142,13 @@ Focus { induce tranceLevel = calculateTranceLevel(6, 3); observe "Calculated trance level: " + tranceLevel; - // ===== ARRAYS UND KOLLEKTIONEN ===== + // ===== ARRAYS UND KOLLEKTIONEN =====; // Array-Literal (falls unterstützt) induce numbers = [1, 2, 3, 4, 5]; induce names = ["Alice", "Bob", "Charlie"]; - // ===== ERWEITERTE FEATURES ===== + // ===== ERWEITERTE FEATURES =====; // Shared Trance (globale Variablen) sharedTrance globalCounter: number = 0; @@ -161,7 +161,7 @@ Focus { // observe "Label reached!"; // if (counter < 10) sinkTo startLabel; - // ===== HYPNOTISCHE SPEZIALEFFEKTE ===== + // ===== HYPNOTISCHE SPEZIALEFFEKTE =====; observe "Starting hypnotic demonstration..."; drift(2000); @@ -175,7 +175,7 @@ Focus { observe "You are now in a deep hypnotic state!"; drift(3000); - // ===== KOMPLEXE BEREICHNUNGEN ===== + // ===== KOMPLEXE BEREICHNUNGEN =====; // Mathematische Funktionen über Builtins induce angle: number = 45; @@ -194,7 +194,7 @@ Focus { observe "Uppercase: " + upperString; observe "Length: " + stringLength; - // ===== FEHLERBEHANDLUNG UND EDGE CASES ===== + // ===== FEHLERBEHANDLUNG UND EDGE CASES =====; // Division durch Null vermeiden induce divisor: number = 0; @@ -205,7 +205,7 @@ Focus { observe "Quotient: " + quotient; } - // ===== FINALE DEMONSTRATION ===== + // ===== FINALE DEMONSTRATION =====; observe "Final demonstration of all features..."; drift(1000); diff --git a/test_advanced.hyp b/hypnoscript-tests/test_advanced.hyp similarity index 92% rename from test_advanced.hyp rename to hypnoscript-tests/test_advanced.hyp index c19a320..2346cc1 100644 --- a/test_advanced.hyp +++ b/hypnoscript-tests/test_advanced.hyp @@ -5,7 +5,7 @@ Focus { observe "Testing all new builtin functions and features..."; } - // ===== NEUE MATHEMATISCHE FUNKTIONEN ===== + // ===== NEUE MATHEMATISCHE FUNKTIONEN =====; observe "=== Testing new mathematical functions ==="; induce x: number = 10.5; @@ -19,7 +19,7 @@ Focus { observe "Random number = " + Random(); observe "Random integer (1-10) = " + RandomInt(1, 10); - // ===== ERWEITERTE STRING-FUNKTIONEN ===== + // ===== ERWEITERTE STRING-FUNKTIONEN =====; observe "=== Testing extended string functions ==="; induce testString: string = " HypnoScript is amazing! "; @@ -34,7 +34,7 @@ Focus { observe "PadLeft(30, '*'): '" + PadLeft(testString, 30, '*') + "'"; observe "PadRight(30, '#'): '" + PadRight(testString, 30, '#') + "'"; - // ===== ARRAY-FUNKTIONEN ===== + // ===== ARRAY-FUNKTIONEN =====; observe "=== Testing array functions ==="; induce numbers = [1, 2, 3, 4, 5]; @@ -51,7 +51,7 @@ Focus { induce combined = ArrayConcat(numbers, moreNumbers); observe "Combined arrays: " + combined; - // ===== KONVERTIERUNGSFUNKTIONEN ===== + // ===== KONVERTIERUNGSFUNKTIONEN =====; observe "=== Testing conversion functions ==="; observe "ToInt(42.7) = " + ToInt(42.7); @@ -61,7 +61,7 @@ Focus { observe "ToBoolean(0) = " + ToBoolean(0); observe "ToChar(65) = " + ToChar(65); - // ===== ERWEITERTE HYPNOTISCHE FUNKTIONEN ===== + // ===== ERWEITERTE HYPNOTISCHE FUNKTIONEN =====; observe "=== Testing extended hypnotic functions ==="; HypnoticVisualization("a beautiful mountain landscape"); @@ -69,7 +69,7 @@ Focus { HypnoticSuggestion("You are becoming more confident with each passing moment"); TranceDeepening(2); - // ===== ZEIT- UND DATUMSFUNKTIONEN ===== + // ===== ZEIT- UND DATUMSFUNKTIONEN =====; observe "=== Testing time and date functions ==="; observe "Current time: " + GetCurrentTime(); @@ -77,7 +77,7 @@ Focus { observe "Current time string: " + GetCurrentTimeString(); observe "Current date/time: " + GetCurrentDateTime(); - // ===== SYSTEM-FUNKTIONEN ===== + // ===== SYSTEM-FUNKTIONEN =====; observe "=== Testing system functions ==="; observe "Environment variable PATH: " + GetEnvironmentVariable("PATH"); @@ -86,7 +86,7 @@ Focus { DebugPrintType("Hello"); DebugPrintType(true); - // ===== KOMPLEXE BEISPIELE ===== + // ===== KOMPLEXE BEISPIELE =====; observe "=== Testing complex examples ==="; // String-Manipulation mit Split und Join @@ -112,7 +112,7 @@ Focus { observe "Array element " + i + ": " + element + " (type: " + ToString(element) + ")"; } - // ===== FINALE DEMONSTRATION ===== + // ===== FINALE DEMONSTRATION =====; observe "=== Final demonstration ==="; // Komplexe Berechnung mit allen Features diff --git a/test_assertions.hyp b/hypnoscript-tests/test_assertions.hyp similarity index 100% rename from test_assertions.hyp rename to hypnoscript-tests/test_assertions.hyp diff --git a/test_basic.hyp b/hypnoscript-tests/test_basic.hyp similarity index 100% rename from test_basic.hyp rename to hypnoscript-tests/test_basic.hyp diff --git a/test_comprehensive.hyp b/hypnoscript-tests/test_comprehensive.hyp similarity index 91% rename from test_comprehensive.hyp rename to hypnoscript-tests/test_comprehensive.hyp index 051339e..655403e 100644 --- a/test_comprehensive.hyp +++ b/hypnoscript-tests/test_comprehensive.hyp @@ -4,7 +4,7 @@ Focus { drift(500); } - // ===== GRUNDLEGENDE FEATURES ===== + // ===== GRUNDLEGENDE FEATURES =====; observe "Testing basic features..."; // Variablendeklarationen @@ -16,7 +16,7 @@ Focus { observe greeting; observe "Counter: " + counter; - // ===== ARITHMETISCHE OPERATIONEN ===== + // ===== ARITHMETISCHE OPERATIONEN =====; observe "Testing arithmetic operations..."; induce x: number = 10; @@ -27,7 +27,7 @@ Focus { induce product: number = x * y; observe "10 * 5 = " + product; - // ===== HYPNOTISCHE OPERATOR-SYNONYME ===== + // ===== HYPNOTISCHE OPERATOR-SYNONYME =====; observe "Testing hypnotic operator synonyms..."; if (counter youAreFeelingVerySleepy 0) deepFocus { @@ -42,7 +42,7 @@ Focus { observe "5 is less than 10 (using fallUnderMySpell)"; } - // ===== KONTROLLSTRUKTUREN ===== + // ===== KONTROLLSTRUKTUREN =====; observe "Testing control structures..."; // While-Schleife @@ -61,7 +61,7 @@ Focus { } } - // ===== ARRAYS ===== + // ===== ARRAYS =====; observe "Testing arrays..."; induce numbers = [1, 2, 3, 4, 5]; @@ -70,7 +70,7 @@ Focus { observe "First number: " + numbers[0]; observe "Second name: " + names[1]; - // ===== FUNKTIONEN ===== + // ===== FUNKTIONEN =====; observe "Testing functions..."; // Einfache Funktion @@ -90,7 +90,7 @@ Focus { printMessage("You are feeling very relaxed..."); - // ===== BUILTIN-FUNKTIONEN ===== + // ===== BUILTIN-FUNKTIONEN =====; observe "Testing builtin functions..."; // Mathematische Funktionen @@ -108,7 +108,7 @@ Focus { observe "Uppercase: " + upperString; observe "Length: " + stringLength; - // ===== TRANCEIFY (STRUKTUREN) ===== + // ===== TRANCEIFY (STRUKTUREN) =====; observe "Testing tranceify structures..."; tranceify Person { @@ -126,7 +126,7 @@ Focus { observe "Person name: " + person.name; observe "Person age: " + person.age; - // ===== SESSIONS (KLASSEN) ===== + // ===== SESSIONS (KLASSEN) =====; observe "Testing sessions (classes)..."; session Hypnotist { @@ -153,7 +153,7 @@ Focus { hypnotist.induceTrance(); hypnotist.greet(); - // ===== HYPNOTISCHE SPEZIALEFFEKTE ===== + // ===== HYPNOTISCHE SPEZIALEFFEKTE =====; observe "Testing hypnotic special effects..."; // Hypnotische Countdown @@ -165,7 +165,7 @@ Focus { observe "You are now in a deep hypnotic state!"; drift(2000); - // ===== FINALE DEMONSTRATION ===== + // ===== FINALE DEMONSTRATION =====; observe "=== Final Demonstration ==="; // Komplexe Berechnung diff --git a/test_enterprise_features.hyp b/hypnoscript-tests/test_enterprise_features.hyp similarity index 94% rename from test_enterprise_features.hyp rename to hypnoscript-tests/test_enterprise_features.hyp index 7b3f7d2..58d062d 100644 --- a/test_enterprise_features.hyp +++ b/hypnoscript-tests/test_enterprise_features.hyp @@ -8,7 +8,7 @@ Focus { drift(500); } - // ===== ERWEITERTE HYPNOTISCHE FUNKTIONEN ===== + // ===== ERWEITERTE HYPNOTISCHE FUNKTIONEN =====; observe "=== Advanced Hypnotic Functions ==="; observe "Starting advanced hypnotic session..."; @@ -21,7 +21,7 @@ Focus { observe "Advanced hypnotic session completed!"; - // ===== DATEI- UND VERZEICHNIS-OPERATIONEN ===== + // ===== DATEI- UND VERZEICHNIS-OPERATIONEN =====; observe "=== File and Directory Operations ==="; // Testdatei erstellen @@ -55,7 +55,7 @@ Focus { observe " Line " + (i + 1) + ": " + ArrayGet(lines, i); } - // ===== JSON-VERARBEITUNG ===== + // ===== JSON-VERARBEITUNG =====; observe "=== JSON Processing ==="; // Komplexes Objekt erstellen @@ -84,7 +84,7 @@ Focus { induce parsedData = FromJson(jsonData); observe "Parsed JSON data: " + parsedData; - // ===== ERWEITERTE MATHEMATISCHE FUNKTIONEN ===== + // ===== ERWEITERTE MATHEMATISCHE FUNKTIONEN =====; observe "=== Advanced Mathematical Functions ==="; observe "Advanced Math Operations:"; @@ -98,7 +98,7 @@ Focus { observe " Atan(1) = " + Atan(1); observe " Atan2(1, 1) = " + Atan2(1, 1); - // ===== ERWEITERTE STRING-FUNKTIONEN ===== + // ===== ERWEITERTE STRING-FUNKTIONEN =====; observe "=== Advanced String Functions ==="; induce sampleText: string = " HypnoScript Runtime Edition is INCREDIBLE! "; @@ -111,7 +111,7 @@ Focus { observe " Count of 'e': " + CountOccurrences(sampleText, "e"); observe " Without whitespace: '" + RemoveWhitespace(sampleText) + "'"; - // ===== ERWEITERTE ARRAY-FUNKTIONEN ===== + // ===== ERWEITERTE ARRAY-FUNKTIONEN =====; observe "=== Advanced Array Functions ==="; induce numbers = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9]; @@ -126,7 +126,7 @@ Focus { observe " Original words: " + words; observe " Unique words: " + ArrayUnique(words); - // ===== KRYPTOLOGISCHE FUNKTIONEN ===== + // ===== KRYPTOLOGISCHE FUNKTIONEN =====; observe "=== Cryptographic Functions ==="; induce secretMessage: string = "HypnoScript is the best programming language ever!"; @@ -142,7 +142,7 @@ Focus { observe " Base64 Encoded: " + base64Encoded; observe " Base64 Decoded: " + base64Decoded; - // ===== ERWEITERTE ZEIT- UND DATUMSFUNKTIONEN ===== + // ===== ERWEITERTE ZEIT- UND DATUMSFUNKTIONEN =====; observe "=== Advanced Time and Date Functions ==="; observe "Advanced Time Information:"; @@ -152,7 +152,7 @@ Focus { observe " Is 2024 Leap Year: " + IsLeapYear(2024); observe " Days in February 2024: " + GetDaysInMonth(2024, 2); - // ===== ERWEITERTE SYSTEM-FUNKTIONEN ===== + // ===== ERWEITERTE SYSTEM-FUNKTIONEN =====; observe "=== Advanced System Functions ==="; observe "System Information:"; @@ -163,7 +163,7 @@ Focus { observe " Processor Count: " + GetProcessorCount(); observe " Working Set: " + GetWorkingSet() + " bytes"; - // ===== ERWEITERTE DEBUGGING-FUNKTIONEN ===== + // ===== ERWEITERTE DEBUGGING-FUNKTIONEN =====; observe "=== Advanced Debugging Functions ==="; DebugPrint("This is a debug message from HypnoScript Runtime"); @@ -174,7 +174,7 @@ Focus { DebugPrintMemory(); DebugPrintEnvironment(); - // ===== KOMPLEXE ALGORITHMEN UND BEISPIELE ===== + // ===== KOMPLEXE ALGORITHMEN UND BEISPIELE =====; observe "=== Complex Algorithms and Examples ==="; // Fibonacci-Funktion mit Session @@ -243,7 +243,7 @@ Focus { observe " Person " + (i + 1) + ": " + personInfo; } - // ===== PERFORMANCE-TEST ===== + // ===== PERFORMANCE-TEST =====; observe "=== Performance Test ==="; induce startTime: number = GetCurrentTime(); @@ -266,7 +266,7 @@ Focus { observe " Duration: " + duration + " seconds"; observe " Operations per second: " + (iterations / duration); - // ===== ERWEITERTE OBJEKTORIENTIERTE PROGRAMMIERUNG ===== + // ===== ERWEITERTE OBJEKTORIENTIERTE PROGRAMMIERUNG =====; observe "=== Advanced Object-Oriented Programming ==="; session AdvancedPerson { @@ -310,7 +310,7 @@ Focus { observe " Has 'AI Programming' skill: " + advancedPerson.hasSkill("AI Programming"); advancedPerson.celebrateBirthday(); - // ===== FINALE DEMONSTRATION ===== + // ===== FINALE DEMONSTRATION =====; observe "=== Final Demonstration ==="; observe "🎉 All Runtime Features Successfully Demonstrated!"; diff --git a/test_enterprise_v3.hyp b/hypnoscript-tests/test_enterprise_v3.hyp similarity index 95% rename from test_enterprise_v3.hyp rename to hypnoscript-tests/test_enterprise_v3.hyp index 24a1ec3..78f425c 100644 --- a/test_enterprise_v3.hyp +++ b/hypnoscript-tests/test_enterprise_v3.hyp @@ -99,7 +99,7 @@ Focus { induce shuffled = StringShuffle("HypnoScript"); observe "Shuffled 'HypnoScript': " + shuffled; - // ===== ERWEITERTE HYPNOTISCHE FUNKTIONEN ===== + // ===== ERWEITERTE HYPNOTISCHE FUNKTIONEN =====; observe "=== Advanced Hypnotic Functions ==="; observe "Starting advanced hypnotic session..."; @@ -112,7 +112,7 @@ Focus { observe "Advanced hypnotic session completed!"; - // ===== DATEI- UND VERZEICHNIS-OPERATIONEN ===== + // ===== DATEI- UND VERZEICHNIS-OPERATIONEN =====; observe "=== File and Directory Operations ==="; // Testdatei erstellen @@ -146,7 +146,7 @@ Focus { observe " Line " + (i + 1) + ": " + ArrayGet(lines, i); } - // ===== JSON-VERARBEITUNG ===== + // ===== JSON-VERARBEITUNG =====; observe "=== JSON Processing ==="; // Komplexes Objekt erstellen @@ -177,7 +177,7 @@ Focus { induce parsedData = FromJson(jsonData); observe "Parsed JSON data: " + parsedData; - // ===== ERWEITERTE MATHEMATISCHE FUNKTIONEN ===== + // ===== ERWEITERTE MATHEMATISCHE FUNKTIONEN =====; observe "=== Advanced Mathematical Functions ==="; observe "Advanced Math Operations:"; @@ -191,7 +191,7 @@ Focus { observe " Atan(1) = " + Atan(1); observe " Atan2(1, 1) = " + Atan2(1, 1); - // ===== ERWEITERTE STRING-FUNKTIONEN ===== + // ===== ERWEITERTE STRING-FUNKTIONEN =====; observe "=== Advanced String Functions ==="; induce sampleText: string = " HypnoScript Edition v1.0.0 is INCREDIBLE! "; @@ -204,7 +204,7 @@ Focus { observe " Count of 'e': " + CountOccurrences(sampleText, "e"); observe " Without whitespace: '" + RemoveWhitespace(sampleText) + "'"; - // ===== ERWEITERTE ARRAY-FUNKTIONEN ===== + // ===== ERWEITERTE ARRAY-FUNKTIONEN =====; observe "=== Advanced Array Functions ==="; induce numbers = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9]; @@ -219,7 +219,7 @@ Focus { observe " Original words: " + words; observe " Unique words: " + ArrayUnique(words); - // ===== KRYPTOLOGISCHE FUNKTIONEN ===== + // ===== KRYPTOLOGISCHE FUNKTIONEN =====; observe "=== Cryptographic Functions ==="; induce secretMessage: string = "HypnoScript Edition v1.0.0 is the best programming language ever!"; @@ -235,7 +235,7 @@ Focus { observe " Base64 Encoded: " + base64Encoded; observe " Base64 Decoded: " + base64Decoded; - // ===== ERWEITERTE ZEIT- UND DATUMSFUNKTIONEN ===== + // ===== ERWEITERTE ZEIT- UND DATUMSFUNKTIONEN =====; observe "=== Advanced Time and Date Functions ==="; observe "Advanced Time Information:"; @@ -245,7 +245,7 @@ Focus { observe " Is 2024 Leap Year: " + IsLeapYear(2024); observe " Days in February 2024: " + GetDaysInMonth(2024, 2); - // ===== ERWEITERTE SYSTEM-FUNKTIONEN ===== + // ===== ERWEITERTE SYSTEM-FUNKTIONEN =====; observe "=== Advanced System Functions ==="; observe "System Information:"; @@ -256,7 +256,7 @@ Focus { observe " Processor Count: " + GetProcessorCount(); observe " Working Set: " + GetWorkingSet() + " bytes"; - // ===== ERWEITERTE DEBUGGING-FUNKTIONEN ===== + // ===== ERWEITERTE DEBUGGING-FUNKTIONEN =====; observe "=== Advanced Debugging Functions ==="; DebugPrint("This is a debug message from HypnoScript v1.0.0"); @@ -267,7 +267,7 @@ Focus { DebugPrintMemory(); DebugPrintEnvironment(); - // ===== KOMPLEXE ALGORITHMEN UND BEISPIELE ===== + // ===== KOMPLEXE ALGORITHMEN UND BEISPIELE =====; observe "=== Complex Algorithms and Examples ==="; // Fibonacci-Funktion mit Session @@ -317,7 +317,7 @@ Focus { induce stats = wizard.calculateStatistics(testData); observe "Statistics: " + stats; - // ===== ERWEITERTE OBJEKTORIENTIERUNG ===== + // ===== ERWEITERTE OBJEKTORIENTIERUNG =====; observe "=== Advanced Object-Oriented Programming ==="; session RuntimePerson { @@ -360,7 +360,7 @@ Focus { induce metadata = enterprisePerson.getMetadata(); observe "Person metadata: " + metadata; - // ===== ERWEITERTE STRUKTUREN ===== + // ===== ERWEITERTE STRUKTUREN =====; observe "=== Advanced Structures ==="; tranceify RuntimeConfig { @@ -381,7 +381,7 @@ Focus { observe "Runtime Config: " + config; - // ===== FINALE DEMONSTRATION ===== + // ===== FINALE DEMONSTRATION =====; observe "=== Final Runtime v1.0.0 Demonstration ==="; observe "🎉 Congratulations! You have successfully experienced HypnoScript Runtime Edition v1.0.0!"; diff --git a/test_extended_features.hyp b/hypnoscript-tests/test_extended_features.hyp similarity index 95% rename from test_extended_features.hyp rename to hypnoscript-tests/test_extended_features.hyp index 2318404..910c819 100644 --- a/test_extended_features.hyp +++ b/hypnoscript-tests/test_extended_features.hyp @@ -6,7 +6,7 @@ Focus { drift(500); } - // ===== ERWEITERTE MATHEMATISCHE FUNKTIONEN ===== + // ===== ERWEITERTE MATHEMATISCHE FUNKTIONEN =====; observe "=== Advanced Mathematical Functions ==="; induce pi: number = 3.14159; @@ -36,7 +36,7 @@ Focus { observe " Random float: " + Random(); observe " Random int (1-100): " + RandomInt(1, 100); - // ===== ERWEITERTE STRING-MANIPULATION ===== + // ===== ERWEITERTE STRING-MANIPULATION =====; observe "=== Advanced String Manipulation ==="; induce sampleText: string = " HypnoScript is absolutely AMAZING! "; @@ -61,7 +61,7 @@ Focus { observe " PadLeft(40, '*'): '" + PadLeft(sampleText, 40, '*') + "'"; observe " PadRight(40, '#'): '" + PadRight(sampleText, 40, '#') + "'"; - // ===== ARRAY-OPERATIONEN ===== + // ===== ARRAY-OPERATIONEN =====; observe "=== Advanced Array Operations ==="; induce primaryArray = [1, 2, 3, 4, 5]; @@ -86,7 +86,7 @@ Focus { observe " Combined arrays: " + combinedArray; observe " Combined length: " + ArrayLength(combinedArray); - // ===== KONVERTIERUNGSFUNKTIONEN ===== + // ===== KONVERTIERUNGSFUNKTIONEN =====; observe "=== Type Conversion Functions ==="; observe "Number Conversions:"; @@ -109,7 +109,7 @@ Focus { observe " ToChar(65) = " + ToChar(65); // 'A' observe " ToChar(97) = " + ToChar(97); // 'a' - // ===== ERWEITERTE HYPNOTISCHE FUNKTIONEN ===== + // ===== ERWEITERTE HYPNOTISCHE FUNKTIONEN =====; observe "=== Extended Hypnotic Functions ==="; observe "Starting hypnotic session..."; @@ -122,7 +122,7 @@ Focus { observe "Hypnotic session completed!"; - // ===== ZEIT- UND DATUMSFUNKTIONEN ===== + // ===== ZEIT- UND DATUMSFUNKTIONEN =====; observe "=== Time and Date Functions ==="; observe "Current Time Information:"; @@ -131,7 +131,7 @@ Focus { observe " Time: " + GetCurrentTimeString(); observe " Full datetime: " + GetCurrentDateTime(); - // ===== SYSTEM-FUNKTIONEN ===== + // ===== SYSTEM-FUNKTIONEN =====; observe "=== System Functions ==="; observe "System Information:"; @@ -144,7 +144,7 @@ Focus { DebugPrintType(true); DebugPrintType(3.14); - // ===== KOMPLEXE BEISPIELE UND ALGORITHMEN ===== + // ===== KOMPLEXE BEISPIELE UND ALGORITHMEN =====; observe "=== Complex Examples and Algorithms ==="; // String parsing and manipulation @@ -194,7 +194,7 @@ Focus { observe " Min: " + min; observe " Max: " + max; - // ===== OBJEKTORIENTIERTE PROGRAMMIERUNG ===== + // ===== OBJEKTORIENTIERTE PROGRAMMIERUNG =====; observe "=== Object-Oriented Programming ==="; session Hypnotist { @@ -236,7 +236,7 @@ Focus { masterHypnotist.performInduction("Alice"); - // ===== STRUKTUREN UND RECORDS ===== + // ===== STRUKTUREN UND RECORDS =====; observe "=== Structures and Records ==="; tranceify HypnoSession { @@ -267,7 +267,7 @@ Focus { observe " Session 1: " + session1.subjectName + " - " + session1.sessionType + " (" + session1.duration + " min)"; observe " Session 2: " + session2.subjectName + " - " + session2.sessionType + " (" + session2.duration + " min)"; - // ===== HYPNOTISCHE OPERATOR-SYNONYME ===== + // ===== HYPNOTISCHE OPERATOR-SYNONYME =====; observe "=== Hypnotic Operator Synonyms ==="; induce a: number = 10; @@ -298,7 +298,7 @@ Focus { observe " b is less than or equal to a (using deeplyLess)"; } - // ===== FINALE DEMONSTRATION ===== + // ===== FINALE DEMONSTRATION =====; observe "=== Final Demonstration ==="; // Complex calculation combining all features diff --git a/hypnoscript-tests/test_new_features.hyp b/hypnoscript-tests/test_new_features.hyp new file mode 100644 index 0000000..819e593 --- /dev/null +++ b/hypnoscript-tests/test_new_features.hyp @@ -0,0 +1,96 @@ +Focus { + + entrance { + observe "=== Test der erweiterten HypnoScript Features ==="; + observe ""; + } + + // Test 1: freeze (const) Variablen + observe "--- Test 1: Freeze (Konstanten) ---"; + freeze PI: number = 3.14159; + observe "PI = " + PI; + observe ""; + + // Test 2: implant (alternative Variablendeklaration) + observe "--- Test 2: Implant (Alternative Var) ---"; + implant secretCode: number = 42; + observe "Secret Code = " + secretCode; + observe ""; + + // Test 3: anchor (Zustand speichern) + observe "--- Test 3: Anchor (Zustand speichern) ---"; + induce counter: number = 100; + anchor savedCounter = counter; + observe "Original Counter: " + counter; + counter = 200; + observe "Geänderter Counter: " + counter; + counter = savedCounter; + observe "Wiederhergestellter Counter: " + counter; + observe ""; + + // Test 4: whisper (Ausgabe ohne Newline) + observe "--- Test 4: Whisper (ohne Newline) ---"; + whisper "Dies "; + whisper "ist "; + whisper "eine "; + whisper "Zeile"; + observe ""; + observe ""; + + // Test 5: command (Imperative Ausgabe) + observe "--- Test 5: Command (Imperativ) ---"; + command "Aufwachen!"; + observe ""; + + // Test 6: oscillate (Boolean Toggle) + observe "--- Test 6: Oscillate (Toggle) ---"; + induce isActive: boolean = false; + observe "isActive vor oscillate: " + isActive; + oscillate isActive; + observe "isActive nach oscillate: " + isActive; + oscillate isActive; + observe "isActive nach 2x oscillate: " + isActive; + observe ""; + + // Test 7: trigger (Event Handler) + observe "--- Test 7: Trigger (Event Handler) ---"; + trigger onEvent = suggestion(message: string) { + observe "Trigger ausgelöst: " + message; + } + + onEvent("Hallo von Trigger!"); + observe ""; + + // Test 8: deepFocus Statement + observe "--- Test 8: DeepFocus Statement ---"; + induce x: number = 15; + if (x > 10) deepFocus { + observe "x ist größer als 10 (deepFocus)"; + observe "Tiefer in die Trance..."; + } + observe ""; + + // Test 9: Hypnotische Operatoren + observe "--- Test 9: Hypnotische Operatoren ---"; + induce a: number = 10; + induce b: number = 10; + + if (a youAreFeelingVerySleepy b) { + observe "a youAreFeelingVerySleepy b (a == b)"; + } + + if (a lookAtTheWatch 5) { + observe "a lookAtTheWatch 5 (a > 5)"; + } + + if (a yourEyesAreGettingHeavy 5) { + observe "a yourEyesAreGettingHeavy 5 (a >= 5)"; + } + observe ""; + + finale { + observe ""; + observe "=== Alle Tests abgeschlossen ==="; + } + +} Relax diff --git a/hypnoscript-tests/test_rust_demo.hyp b/hypnoscript-tests/test_rust_demo.hyp new file mode 100644 index 0000000..6c65111 --- /dev/null +++ b/hypnoscript-tests/test_rust_demo.hyp @@ -0,0 +1,18 @@ +Focus { + entrance { + observe "Welcome to HypnoScript Rust Edition!"; + } + + induce x: number = 42; + induce message: string = "Hello Trance"; + + observe message; + observe x; + + if (x > 40) deepFocus { + observe "X is greater than 40"; + } + + induce sum: number = x + 8; + observe sum; +} Relax; diff --git a/test_simple.hyp b/hypnoscript-tests/test_simple.hyp similarity index 100% rename from test_simple.hyp rename to hypnoscript-tests/test_simple.hyp diff --git a/hypnoscript-tests/test_simple_features.hyp b/hypnoscript-tests/test_simple_features.hyp new file mode 100644 index 0000000..8d8e704 --- /dev/null +++ b/hypnoscript-tests/test_simple_features.hyp @@ -0,0 +1,61 @@ +Focus { + + entrance { + observe "Test der erweiterten Features"; + } + + // Test freeze + freeze PI: number = 3.14159; + observe "Freeze Test OK"; + + // Test implant + implant code: number = 42; + observe "Implant Test OK"; + + // Test anchor + induce x: number = 100; + anchor saved = x; + x = 200; + x = saved; + observe "Anchor Test OK"; + + // Test whisper + whisper "Whisper "; + whisper "Test "; + observe "OK"; + + // Test command + command "Command Test"; + + // Test oscillate + induce flag: boolean = false; + oscillate flag; + if (flag) { + observe "Oscillate Test OK"; + } + + // Test trigger + trigger myTrigger = suggestion() { + observe "Trigger Test OK"; + } + myTrigger(); + + // Test deepFocus + induce y: number = 15; + if (y > 10) deepFocus { + observe "DeepFocus Test OK"; + } + + // Test hypnotic operators + induce a: number = 10; + induce b: number = 10; + + if (a youAreFeelingVerySleepy b) { + observe "Hypnotic Operator Test OK"; + } + + finale { + observe "Alle Tests erfolgreich"; + } + +} Relax diff --git a/package.json b/package.json new file mode 100644 index 0000000..0faa706 --- /dev/null +++ b/package.json @@ -0,0 +1,61 @@ +{ + "name": "hyp-runtime", + "version": "1.0.0-rc1", + "description": "Workspace documentation tooling for the HypnoScript Rust implementation.", + "private": true, + "scripts": { + "build": "cargo build --release --workspace", + "build:cli": "cargo build --release --package hypnoscript-cli", + "build:compiler": "cargo build --release --package hypnoscript-compiler", + "build:core": "cargo build --release --package hypnoscript-core", + "build:lexer-parser": "cargo build --release --package hypnoscript-lexer-parser", + "build:runtime": "cargo build --release --package hypnoscript-runtime", + "build:dev": "cargo build --workspace", + "format": "cargo fmt --all", + "format:check": "cargo fmt --all -- --check", + "lint": "cargo clippy --all-targets --all-features -- -D warnings", + "lint:fix": "cargo clippy --all-targets --all-features --fix", + "test": "cargo test --workspace --verbose", + "test:cli": "cargo test --package hypnoscript-cli --verbose", + "test:compiler": "cargo test --package hypnoscript-compiler --verbose", + "test:core": "cargo test --package hypnoscript-core --verbose", + "test:lexer-parser": "cargo test --package hypnoscript-lexer-parser --verbose", + "test:runtime": "cargo test --package hypnoscript-runtime --verbose", + "test:integration": "cargo test --workspace --test '*' --verbose", + "test:coverage": "cargo llvm-cov --all-features --workspace --lcov --output-path lcov.info", + "clean": "cargo clean", + "check": "cargo check --workspace", + "audit": "cargo audit", + "doc": "cargo doc --no-deps --workspace --open", + "doc:build": "cargo doc --no-deps --workspace", + "docs:dev": "cd hypnoscript-docs && npm run dev", + "docs:build": "cd hypnoscript-docs && npm run build", + "docs:preview": "cd hypnoscript-docs && npm run preview", + "docs:install": "cd hypnoscript-docs && npm ci", + "release:prepare": "npm run format && npm run lint && npm run test && npm run build", + "release:linux": "pwsh scripts/build_linux.ps1", + "release:macos": "pwsh scripts/build_macos.ps1", + "release:macos:universal": "pwsh scripts/build_macos.ps1 -Architecture universal", + "release:macos:x64": "pwsh scripts/build_macos.ps1 -Architecture x64", + "release:macos:arm64": "pwsh scripts/build_macos.ps1 -Architecture arm64", + "release:macos:dmg": "pwsh scripts/build_macos.ps1 -PackageType dmg", + "release:macos:pkg": "pwsh scripts/build_macos.ps1 -PackageType pkg", + "release:windows": "pwsh scripts/build_winget.ps1", + "release:all": "npm run release:prepare && npm run release:windows && npm run release:linux && npm run release:macos", + "cli:version": "cargo run --release --package hypnoscript-cli -- version", + "cli:builtins": "cargo run --release --package hypnoscript-cli -- builtins", + "cli:test": "cargo run --release --package hypnoscript-cli -- run hypnoscript-tests/test_rust_demo.hyp" + }, + "repository": { + "type": "git", + "url": "https://github.com/Kink-Development-Group/hyp-runtime.git" + }, + "keywords": [ + "hypnoscript", + "rust", + "documentation", + "vitepress" + ], + "author": "HypnoScript Team", + "license": "MIT" +} diff --git a/scripts/README.md b/scripts/README.md index 59dc5a8..e31acc5 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -1,27 +1,342 @@ -# scripts/ - Build- und Paketierungsskripte +# HypnoScript Build Scripts -## Windows (winget) +This directory contains build and packaging scripts for creating release artifacts of HypnoScript. -- **build_winget.ps1**: Baut das self-contained Windows-Binary und erstellt ein ZIP für winget. -- **winget-manifest.yaml**: Beispiel für das winget-Manifest. SHA256 muss nach jedem Release angepasst werden. +## 📦 Available Scripts -**Veröffentlichung:** +### Windows Release -1. Release-ZIP auf GitHub hochladen -2. SHA256 berechnen und im Manifest eintragen -3. Manifest als Pull Request im [winget-pkgs](https://github.com/microsoft/winget-pkgs) Repository einreichen +**Script**: `build_winget.ps1` +**Usage**: `npm run release:windows` or `pwsh scripts/build_winget.ps1` -## Linux (APT) +Creates a Windows release package including: -- **build_deb.sh**: Baut das self-contained Linux-Binary und erzeugt ein .deb-Paket (benötigt `fpm`). -- **debian/**: Beispielstruktur für ein Debian-Paket (control, postinst, prerm) +- ✅ Optimized binary (`hypnoscript.exe`) +- ✅ ZIP archive for distribution +- ✅ SHA256 checksum +- ✅ WinGet manifest update -**Veröffentlichung:** +**Output**: -1. .deb-Paket auf GitHub Releases hochladen oder eigenes APT-Repo einrichten -2. Optional: Repository mit `apt-add-repository` bereitstellen -3. Nutzer können mit `sudo apt install hypnoscript` installieren +- `release/windows-x64/hypnoscript.exe` +- `release/HypnoScript-windows-x64.zip` +- `release/HypnoScript-windows-x64.zip.sha256` + +**Requirements**: + +- PowerShell 7+ +- Rust toolchain (cargo) + +--- + +### Linux Release + +**Script**: `build_linux.ps1` +**Usage**: `npm run release:linux` or `pwsh scripts/build_linux.ps1` + +Creates a Linux release package including: + +- ✅ Binary for Linux (`hypnoscript`) +- ✅ TAR.GZ archive for distribution +- ✅ Installation script +- ✅ SHA256 checksum + +**Output**: + +- `release/linux-x64/hypnoscript` +- `release/linux-x64/install.sh` +- `release/hypnoscript-1.0.0-linux-x64.tar.gz` +- `release/hypnoscript-1.0.0-linux-x64.tar.gz.sha256` + +**Requirements**: + +- PowerShell 7+ (cross-platform) +- Rust toolchain (cargo) +- Optional: Linux cross-compilation target (`rustup target add x86_64-unknown-linux-gnu`) + +**Installation on Linux**: + +```bash +tar -xzf hypnoscript-1.0.0-linux-x64.tar.gz +cd linux-x64 +sudo bash install.sh +``` + +--- + +### macOS Release + +**Script**: `build_macos.ps1` +**Usage**: `npm run release:macos` or `pwsh scripts/build_macos.ps1` + +Creates a macOS release package with multiple distribution formats: + +- ✅ Universal Binary (Intel + Apple Silicon) +- ✅ TAR.GZ archive for distribution +- ✅ DMG disk image (macOS only) +- ✅ PKG installer (macOS only) +- ✅ Installation script +- ✅ SHA256 checksums + +**Output**: + +- `release/macos-universal/hypnoscript` +- `release/macos-universal/install.sh` +- `release/HypnoScript-1.0.0-macos-universal.tar.gz` +- `release/HypnoScript-1.0.0-macos-universal.dmg` (macOS only) +- `release/HypnoScript-1.0.0-macos-universal.pkg` (macOS only) +- `.sha256` files for all archives + +**Architecture Options**: + +```bash +npm run release:macos # Universal (Intel + Apple Silicon) +npm run release:macos:x64 # Intel only +npm run release:macos:arm64 # Apple Silicon only +``` + +**Package Type Options**: + +```bash +npm run release:macos:dmg # DMG only (requires macOS) +npm run release:macos:pkg # PKG only (requires macOS) +pwsh scripts/build_macos.ps1 -PackageType tar.gz # TAR.GZ only +pwsh scripts/build_macos.ps1 -PackageType all # All formats +``` + +**Requirements**: + +- PowerShell 7+ (cross-platform) +- Rust toolchain (cargo) +- macOS targets: `rustup target add x86_64-apple-darwin aarch64-apple-darwin` +- DMG/PKG creation requires macOS with `hdiutil` and `pkgbuild` + +**Installation on macOS**: + +From TAR.GZ: + +```bash +tar -xzf HypnoScript-1.0.0-macos-universal.tar.gz +cd macos-universal +sudo bash install.sh +``` + +From DMG: + +1. Open `HypnoScript-1.0.0-macos-universal.dmg` +2. Drag `hypnoscript` to the "Install to /usr/local/bin" symlink + +From PKG: + +```bash +sudo installer -pkg HypnoScript-1.0.0-macos-universal.pkg -target / +``` + +--- + +### Debian Package (Legacy) + +**Script**: `build_deb.sh` (deprecated in favor of `build_linux.ps1`) +**Usage**: `bash scripts/build_deb.sh` + +Creates a `.deb` package for Debian/Ubuntu systems. + +**Requirements**: + +- Bash +- Ruby gem: `fpm` (install via `gem install fpm`) +- Rust toolchain + +**Note**: This script has cross-platform issues when run on Windows. Use `build_linux.ps1` instead. + +--- + +## 🚀 Complete Release Pipeline + +To prepare and build releases for all platforms: + +```bash +# 1. Prepare: Format, Lint, Test, Build +npm run release:prepare + +# 2. Build platform-specific packages +npm run release:windows # Windows x64 +npm run release:linux # Linux x64 +npm run release:macos # macOS Universal (Intel + Apple Silicon) + +# Or build all at once +npm run release:all +``` + +## 🏗️ Architecture Support + +### Windows + +- ✅ **x64** (Intel/AMD 64-bit) - Full support + +### Linux + +- ✅ **x64** (Intel/AMD 64-bit) - Full support +- 🔄 ARM64 - Possible with `rustup target add aarch64-unknown-linux-gnu` + +### macOS + +- ✅ **x64** (Intel) - Full support +- ✅ **ARM64** (Apple Silicon) - Full support +- ✅ **Universal** (Intel + Apple Silicon) - Full support with `lipo` + +--- + +## 🛠 Cross-Compilation Setup + +### Linux Target (for building Linux binaries on Windows/macOS) + +```bash +rustup target add x86_64-unknown-linux-gnu +``` + +### Windows Target (for building Windows binaries on Linux/macOS) + +```bash +rustup target add x86_64-pc-windows-msvc +``` + +### macOS Targets (for building macOS binaries on any platform) + +```bash +rustup target add x86_64-apple-darwin # Intel +rustup target add aarch64-apple-darwin # Apple Silicon +``` + +**Note**: Creating Universal binaries and DMG/PKG installers requires running on macOS. + +--- + +## 📝 Version Management + +Version information is defined in: + +- `Cargo.toml` (workspace root) +- `scripts/build_winget.ps1` (line 8: `$VERSION = "1.0.0"`) +- `scripts/build_linux.ps1` (line 10: `$VERSION = "1.0.0"`) +- `scripts/build_macos.ps1` (line 11: `$VERSION = "1.0.0"`) +- `scripts/build_deb.sh` (line 7: `VERSION=1.0.0`) + +**Important**: Keep versions synchronized across all files! + +--- + +## 🔐 Checksum Verification + +All release packages include SHA256 checksums: + +**Windows**: + +```powershell +Get-FileHash -Algorithm SHA256 HypnoScript-windows-x64.zip +``` + +**Linux**: + +```bash +sha256sum hypnoscript-1.0.0-linux-x64.tar.gz +cat hypnoscript-1.0.0-linux-x64.tar.gz.sha256 +``` + +**macOS**: + +```bash +shasum -a 256 HypnoScript-1.0.0-macos-universal.tar.gz +cat HypnoScript-1.0.0-macos-universal.tar.gz.sha256 +``` + +--- + +## 📊 Build Artifacts + +After running release scripts, the `release/` directory contains: + +```text +release/ +├── windows-x64/ +│ ├── hypnoscript.exe +│ ├── README.md +│ ├── LICENSE +│ └── VERSION.txt +├── linux-x64/ +│ ├── hypnoscript +│ ├── install.sh +│ ├── README.md +│ ├── LICENSE +│ └── VERSION.txt +├── macos-universal/ +│ ├── hypnoscript +│ ├── install.sh +│ ├── README.md +│ ├── LICENSE +│ └── VERSION.txt +├── HypnoScript-windows-x64.zip +├── HypnoScript-windows-x64.zip.sha256 +├── hypnoscript-1.0.0-linux-x64.tar.gz +├── hypnoscript-1.0.0-linux-x64.tar.gz.sha256 +├── HypnoScript-1.0.0-macos-universal.tar.gz +├── HypnoScript-1.0.0-macos-universal.tar.gz.sha256 +├── HypnoScript-1.0.0-macos-universal.dmg (macOS only) +├── HypnoScript-1.0.0-macos-universal.dmg.sha256 +├── HypnoScript-1.0.0-macos-universal.pkg (macOS only) +└── HypnoScript-1.0.0-macos-universal.pkg.sha256 +``` + +--- + +## 🐛 Troubleshooting + +### "cargo: command not found" + +Ensure Rust is installed: + +```bash +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh +``` + +### Cross-compilation linker errors + +Install the required linker for your target platform: + +**For Linux target on Windows**: + +- Install WSL2 with Ubuntu +- Or use cross-compilation tools like `cross` + +**For Windows target on Linux**: + +```bash +sudo apt install mingw-w64 +``` + +### PowerShell execution policy error + +```powershell +Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser +``` + +## 📚 Publishing + +### WinGet (Windows Package Manager) + +1. Upload release ZIP to GitHub Releases +2. Update `winget-manifest.yaml` with new SHA256 +3. Submit manifest as Pull Request to [winget-pkgs](https://github.com/microsoft/winget-pkgs) + +### GitHub Releases + +1. Create a new release tag (e.g., `v1.0.0`) +2. Upload artifacts: + - `HypnoScript-windows-x64.zip` + - `hypnoscript-1.0.0-linux-x64.tar.gz` + - Checksum files (`.sha256`) +3. Add release notes --- -**Hinweis:** Für beide Plattformen werden self-contained Binaries verwendet, sodass keine separate .NET-Installation notwendig ist. +**Note**: All binaries are statically compiled with Rust and don't require external dependencies! diff --git a/scripts/build_deb.sh b/scripts/build_deb.sh index caef128..e884b88 100644 --- a/scripts/build_deb.sh +++ b/scripts/build_deb.sh @@ -1,30 +1,137 @@ #!/bin/bash set -e -# Check for fpm -if ! command -v fpm >/dev/null 2>&1; then - echo 'Error: fpm is not installed. Please install fpm (e.g. via `gem install fpm`) before running this script.' >&2 - exit 1 -fi - # build_deb.sh -# Erstellt self-contained Linux-Binary und .deb-Paket +# Erstellt Linux-Binary und .deb-Paket für HypnoScript (Rust-Implementation) NAME=hypnoscript VERSION=1.0.0 ARCH=amd64 -PUBLISH_DIR=../publish/linux -DEB_OUT=../publish/${NAME}_${VERSION}_${ARCH}.deb -# 1. Build -echo 'Baue self-contained Linux-Binary...' -dotnet publish ../HypnoScript.CLI -c Release -r linux-x64 --self-contained true -p:PublishSingleFile=true -o $PUBLISH_DIR +# Projektverzeichnis ermitteln +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" + +RELEASE_DIR="$PROJECT_ROOT/release/linux-x64" +TAR_OUT="$PROJECT_ROOT/release/${NAME}-${VERSION}-linux-x64.tar.gz" +DEB_OUT="$PROJECT_ROOT/release/${NAME}_${VERSION}_${ARCH}.deb" +BINARY_NAME=hypnoscript-cli +INSTALL_NAME=hypnoscript + +# Check if fpm is available (optional) +HAS_FPM=false +if command -v fpm >/dev/null 2>&1; then + HAS_FPM=true + echo "✓ fpm found - will create .deb package" +else + echo "⚠ fpm not found - will create tar.gz archive only" + echo " (Install fpm via 'gem install fpm' to enable .deb packaging)" +fi + +# Check for cargo +if ! command -v cargo >/dev/null 2>&1; then + # Try to find cargo in common Windows locations + if [ -f "$HOME/.cargo/bin/cargo" ]; then + export PATH="$HOME/.cargo/bin:$PATH" + elif [ -f "$USERPROFILE/.cargo/bin/cargo.exe" ]; then + export PATH="$USERPROFILE/.cargo/bin:$PATH" + else + echo 'Error: cargo is not installed. Please install Rust toolchain first.' >&2 + echo 'Visit https://rustup.rs/ to install Rust' >&2 + exit 1 + fi +fi + +echo "=== HypnoScript Linux Release Builder ===" +echo "" + +# 1. Verzeichnisse vorbereiten +echo "📦 Preparing release directory..." +rm -rf "$RELEASE_DIR" +mkdir -p "$RELEASE_DIR" + +# 2. Build +echo "🔨 Building HypnoScript CLI (Release)..." +cd "$PROJECT_ROOT" +cargo build --release --package hypnoscript-cli + +# 3. Binary kopieren +echo "📋 Copying binary..." +cp "target/release/$BINARY_NAME" "$RELEASE_DIR/$INSTALL_NAME" +chmod +x "$RELEASE_DIR/$INSTALL_NAME" + +# 4. Zusätzliche Dateien +echo "📄 Adding additional files..." +if [ -f "$PROJECT_ROOT/README.md" ]; then + cp "$PROJECT_ROOT/README.md" "$RELEASE_DIR/" +fi + +if [ -f "$PROJECT_ROOT/LICENSE" ]; then + cp "$PROJECT_ROOT/LICENSE" "$RELEASE_DIR/" +fi + +echo "$VERSION" > "$RELEASE_DIR/VERSION.txt" + +# 5. TAR.GZ-Archiv erstellen (immer) +echo "📦 Creating TAR.GZ archive..." +cd "$PROJECT_ROOT/release" +tar -czf "$(basename "$TAR_OUT")" -C linux-x64 . +cd "$PROJECT_ROOT" -# 2. Paket bauen (fpm erforderlich) -echo 'Erzeuge .deb-Paket...' -fpm -s dir -t deb -n $NAME -v $VERSION --prefix /usr/local/bin $PUBLISH_DIR/HypnoScript.CLI=$NAME +# 6. .deb-Paket bauen (nur wenn fpm verfügbar) +if [ "$HAS_FPM" = true ]; then + echo "📦 Creating .deb package..." + fpm -s dir \ + -t deb \ + -n "$NAME" \ + -v "$VERSION" \ + --architecture "$ARCH" \ + --description "HypnoScript - Esoterische Programmiersprache mit Hypnose-Metaphern" \ + --url "https://github.com/Kink-Development-Group/hyp-runtime" \ + --license "MIT" \ + --maintainer "HypnoScript Team" \ + --prefix /usr/local/bin \ + --deb-compression xz \ + "$RELEASE_DIR/$INSTALL_NAME=$INSTALL_NAME" + + # Paket verschieben + mv "${NAME}_${VERSION}_${ARCH}.deb" "$DEB_OUT" + + # Checksum erstellen + echo "🔐 Generating SHA256 checksum for .deb..." + sha256sum "$DEB_OUT" > "${DEB_OUT}.sha256" +fi -# 3. Paket verschieben -mv ${NAME}_${VERSION}_${ARCH}.deb $DEB_OUT +# 7. Checksum für TAR.GZ erstellen +echo "🔐 Generating SHA256 checksum for tar.gz..." +sha256sum "$TAR_OUT" > "${TAR_OUT}.sha256" + +# 8. Informationen ausgeben +echo "" +echo "✅ Build complete!" +echo "📦 TAR.GZ Archive: $TAR_OUT" +echo "🔐 TAR.GZ Checksum: ${TAR_OUT}.sha256" + +if [ "$HAS_FPM" = true ]; then + echo "📦 DEB Package: $DEB_OUT" + echo "🔐 DEB Checksum: ${DEB_OUT}.sha256" + echo "" + echo "DEB Package size: $(du -h "$DEB_OUT" | cut -f1)" +fi + +echo "" +echo "TAR.GZ size: $(du -h "$TAR_OUT" | cut -f1)" +echo "" +echo "To install from TAR.GZ:" +echo " tar -xzf $TAR_OUT" +echo " sudo mv hypnoscript /usr/local/bin/" + +if [ "$HAS_FPM" = true ]; then + echo "" + echo "To install from DEB:" + echo " sudo dpkg -i $DEB_OUT" +fi -echo "Fertig! .deb-Paket liegt in $DEB_OUT" +echo "" +echo "To verify:" +echo " hypnoscript --version" diff --git a/scripts/build_linux.ps1 b/scripts/build_linux.ps1 new file mode 100644 index 0000000..93e45e4 --- /dev/null +++ b/scripts/build_linux.ps1 @@ -0,0 +1,162 @@ +#!/usr/bin/env pwsh +# build_linux.ps1 +# Erstellt Linux-Binary und TAR.GZ-Archiv für HypnoScript (Rust-Implementation) +# Kann unter Windows mit WSL oder direkt unter Linux ausgeführt werden + +param( + [switch]$SkipBuild = $false +) + +$ErrorActionPreference = "Stop" + +# Konfiguration +$NAME = "hypnoscript" +$VERSION = "1.0.0" +$ARCH = "amd64" + +# Projektverzeichnis ermitteln +$ScriptDir = Split-Path -Parent $PSScriptRoot +$ProjectRoot = $ScriptDir +$ReleaseDir = Join-Path $ProjectRoot "release" "linux-x64" +$TarOut = Join-Path $ProjectRoot "release" "$NAME-$VERSION-linux-x64.tar.gz" +$BinaryName = "hypnoscript-cli" +$InstallName = "hypnoscript" + +Write-Host "=== HypnoScript Linux Release Builder ===" -ForegroundColor Cyan +Write-Host "" + +# Check für Cargo +if (-not (Get-Command cargo -ErrorAction SilentlyContinue)) { + Write-Host "Error: cargo is not installed. Please install Rust toolchain first." -ForegroundColor Red + Write-Host "Visit https://rustup.rs/ to install Rust" -ForegroundColor Yellow + exit 1 +} + +# 1. Verzeichnisse vorbereiten +Write-Host "📦 Preparing release directory..." -ForegroundColor Green +if (Test-Path $ReleaseDir) { + Remove-Item -Recurse -Force $ReleaseDir +} +New-Item -ItemType Directory -Force -Path $ReleaseDir | Out-Null + +# 2. Build für Linux (falls WSL verfügbar, sonst für aktuelles System) +if (-not $SkipBuild) { + Write-Host "🔨 Building HypnoScript CLI (Release for Linux)..." -ForegroundColor Green + Push-Location $ProjectRoot + + # Versuche Cross-Compilation für Linux + $LinuxTarget = "x86_64-unknown-linux-gnu" + + # Check ob Linux-Target installiert ist + $InstalledTargets = rustup target list --installed 2>$null + if ($InstalledTargets -match $LinuxTarget) { + Write-Host " Using cross-compilation target: $LinuxTarget" -ForegroundColor Cyan + cargo build --release --package hypnoscript-cli --target $LinuxTarget + $BinaryPath = Join-Path "target" $LinuxTarget "release" $BinaryName + } else { + Write-Host " ⚠ Linux target not installed, building for current platform" -ForegroundColor Yellow + Write-Host " (To enable Linux builds: rustup target add $LinuxTarget)" -ForegroundColor Yellow + cargo build --release --package hypnoscript-cli + $BinaryPath = Join-Path "target" "release" "$BinaryName.exe" + } + + Pop-Location +} else { + Write-Host "⏩ Skipping build (using existing binary)..." -ForegroundColor Yellow + $BinaryPath = Join-Path $ProjectRoot "target" "release" $BinaryName +} + +# 3. Binary kopieren +Write-Host "📋 Copying binary..." -ForegroundColor Green +$DestBinary = Join-Path $ReleaseDir $InstallName +Copy-Item $BinaryPath $DestBinary -Force + +# 4. Zusätzliche Dateien +Write-Host "📄 Adding additional files..." -ForegroundColor Green + +$ReadmePath = Join-Path $ProjectRoot "README.md" +if (Test-Path $ReadmePath) { + Copy-Item $ReadmePath $ReleaseDir +} + +$LicensePath = Join-Path $ProjectRoot "LICENSE" +if (Test-Path $LicensePath) { + Copy-Item $LicensePath $ReleaseDir +} + +Set-Content -Path (Join-Path $ReleaseDir "VERSION.txt") -Value $VERSION + +# Installation-Script erstellen +$InstallScript = @" +#!/bin/bash +# HypnoScript Installation Script + +set -e + +INSTALL_DIR="/usr/local/bin" +BINARY_NAME="hypnoscript" + +echo "Installing HypnoScript to `$INSTALL_DIR..." + +# Check for sudo +if [ "`$EUID" -ne 0 ]; then + echo "Please run with sudo:" + echo " sudo bash install.sh" + exit 1 +fi + +# Copy binary +cp `$BINARY_NAME `$INSTALL_DIR/`$BINARY_NAME +chmod +x `$INSTALL_DIR/`$BINARY_NAME + +echo "✓ HypnoScript installed successfully!" +echo "" +echo "Run 'hypnoscript --version' to verify the installation." +"@ + +Set-Content -Path (Join-Path $ReleaseDir "install.sh") -Value $InstallScript + +# 5. TAR.GZ-Archiv erstellen +Write-Host "📦 Creating TAR.GZ archive..." -ForegroundColor Green + +# Unter Windows: tar.exe verwenden (verfügbar ab Windows 10 1803) +if ($IsWindows -or ($PSVersionTable.PSVersion.Major -le 5)) { + Push-Location (Join-Path $ProjectRoot "release") + & tar -czf (Split-Path -Leaf $TarOut) -C "linux-x64" . + Pop-Location +} else { + # Unter Linux: natives tar + Push-Location (Join-Path $ProjectRoot "release") + tar -czf (Split-Path -Leaf $TarOut) -C "linux-x64" . + Pop-Location +} + +# 6. Checksum erstellen +Write-Host "🔐 Generating SHA256 checksum..." -ForegroundColor Green +$Hash = Get-FileHash -Path $TarOut -Algorithm SHA256 +$HashString = "$($Hash.Hash.ToLower()) $(Split-Path -Leaf $TarOut)" +Set-Content -Path "$TarOut.sha256" -Value $HashString + +# 7. Informationen ausgeben +Write-Host "" +Write-Host "✅ Build complete!" -ForegroundColor Green +Write-Host "📦 TAR.GZ Archive: $TarOut" -ForegroundColor Cyan +Write-Host "🔐 Checksum: $TarOut.sha256" -ForegroundColor Cyan +Write-Host "" + +$TarSize = (Get-Item $TarOut).Length / 1MB +Write-Host "Archive size: $([math]::Round($TarSize, 2)) MB" +Write-Host "" + +Write-Host "To install on Linux:" -ForegroundColor Yellow +Write-Host " tar -xzf $(Split-Path -Leaf $TarOut)" -ForegroundColor White +Write-Host " cd linux-x64" -ForegroundColor White +Write-Host " sudo bash install.sh" -ForegroundColor White +Write-Host "" +Write-Host "Or manually:" -ForegroundColor Yellow +Write-Host " sudo mv hypnoscript /usr/local/bin/" -ForegroundColor White +Write-Host "" +Write-Host "To verify:" -ForegroundColor Yellow +Write-Host " hypnoscript --version" -ForegroundColor White +Write-Host "" +Write-Host "✓ All done!" -ForegroundColor Green diff --git a/scripts/build_macos.ps1 b/scripts/build_macos.ps1 new file mode 100644 index 0000000..880def7 --- /dev/null +++ b/scripts/build_macos.ps1 @@ -0,0 +1,387 @@ +#!/usr/bin/env pwsh +# build_macos.ps1 +# Erstellt macOS-Binary und DMG/PKG für HypnoScript (Rust-Implementation) +# Kann unter Windows/Linux mit Cross-Compilation oder nativ auf macOS ausgeführt werden + +param( + [switch]$SkipBuild = $false, + [ValidateSet('x64', 'arm64', 'universal')] + [string]$Architecture = 'universal', + [ValidateSet('dmg', 'pkg', 'tar.gz', 'all')] + [string]$PackageType = 'all' +) + +$ErrorActionPreference = "Stop" + +# Konfiguration +$NAME = "HypnoScript" +$BUNDLE_ID = "com.kinkdev.hypnoscript" +$VERSION = "1.0.0" +$BINARY_NAME = "hypnoscript-cli" +$INSTALL_NAME = "hypnoscript" + +# Projektverzeichnis ermitteln +$ScriptDir = Split-Path -Parent $PSScriptRoot +$ProjectRoot = $ScriptDir +$ReleaseDir = Join-Path $ProjectRoot "release" "macos-$Architecture" + +Write-Host "=== HypnoScript macOS Release Builder ===" -ForegroundColor Cyan +Write-Host "Architecture: $Architecture" -ForegroundColor Yellow +Write-Host "Package Type: $PackageType" -ForegroundColor Yellow +Write-Host "" + +# Check für Cargo +if (-not (Get-Command cargo -ErrorAction SilentlyContinue)) { + Write-Host "Error: cargo is not installed. Please install Rust toolchain first." -ForegroundColor Red + Write-Host "Visit https://rustup.rs/ to install Rust" -ForegroundColor Yellow + exit 1 +} + +# Detect current OS +$RunningOnMacOS = $RunningOnMacOS -or ($PSVersionTable.PSVersion.Major -ge 6 -and $PSVersionTable.OS -like "*Darwin*") +$RunningOnLinux = $RunningOnLinux -or ($PSVersionTable.PSVersion.Major -ge 6 -and $PSVersionTable.OS -like "*Linux*") +$RunningOnWindows = $RunningOnWindows -or ($PSVersionTable.PSVersion.Major -le 5) -or ($PSVersionTable.OS -like "*Windows*") + +# Target definitions +$TargetX64 = "x86_64-apple-darwin" +$TargetArm64 = "aarch64-apple-darwin" + +# 1. Verzeichnisse vorbereiten +Write-Host "📦 Preparing release directory..." -ForegroundColor Green +if (Test-Path $ReleaseDir) { + Remove-Item -Recurse -Force $ReleaseDir +} +New-Item -ItemType Directory -Force -Path $ReleaseDir | Out-Null + +# 2. Build +if (-not $SkipBuild) { + Write-Host "🔨 Building HypnoScript CLI for macOS ($Architecture)..." -ForegroundColor Green + + # Check if we're on a non-macOS system - cross compilation needs special setup + if (-not $RunningOnMacOS) { + Write-Host "" + Write-Host "⚠ Warning: Cross-compiling for macOS from Windows/Linux" -ForegroundColor Yellow + Write-Host " This requires:" -ForegroundColor Yellow + Write-Host " - macOS SDK/toolchain" -ForegroundColor Yellow + Write-Host " - C linker for macOS (cc)" -ForegroundColor Yellow + Write-Host "" + Write-Host " Recommended: Run this script on macOS for best results" -ForegroundColor Yellow + Write-Host " Or use: npm run release:windows / npm run release:linux" -ForegroundColor Yellow + Write-Host "" + Write-Host " Skipping build - documentation-only release will be created" -ForegroundColor Cyan + Write-Host "" + $SkipBuild = $true + } else { + Push-Location $ProjectRoot + + if ($Architecture -eq 'universal') { + # Universal Binary (beide Architekturen) + Write-Host " Building for x86_64 (Intel)..." -ForegroundColor Cyan + + # Check if targets are installed + $InstalledTargets = rustup target list --installed 2>$null + + if (-not ($InstalledTargets -match $TargetX64)) { + Write-Host " Installing target: $TargetX64" -ForegroundColor Yellow + rustup target add $TargetX64 + } + + if (-not ($InstalledTargets -match $TargetArm64)) { + Write-Host " Installing target: $TargetArm64" -ForegroundColor Yellow + rustup target add $TargetArm64 + } + + cargo build --release --package hypnoscript-cli --target $TargetX64 + Write-Host " Building for aarch64 (Apple Silicon)..." -ForegroundColor Cyan + cargo build --release --package hypnoscript-cli --target $TargetArm64 + + # Create universal binary with lipo + Write-Host " Creating universal binary with lipo..." -ForegroundColor Cyan + $BinaryX64 = Join-Path "target" $TargetX64 "release" $BINARY_NAME + $BinaryArm64 = Join-Path "target" $TargetArm64 "release" $BINARY_NAME + $BinaryUniversal = Join-Path $ReleaseDir $INSTALL_NAME + + & lipo -create $BinaryX64 $BinaryArm64 -output $BinaryUniversal + chmod +x $BinaryUniversal + } elseif ($Architecture -eq 'x64') { + # Nur Intel + cargo build --release --package hypnoscript-cli --target $TargetX64 + $BinaryPath = Join-Path "target" $TargetX64 "release" $BINARY_NAME + Copy-Item $BinaryPath (Join-Path $ReleaseDir $INSTALL_NAME) + } elseif ($Architecture -eq 'arm64') { + # Nur Apple Silicon + cargo build --release --package hypnoscript-cli --target $TargetArm64 + $BinaryPath = Join-Path "target" $TargetArm64 "release" $BINARY_NAME + Copy-Item $BinaryPath (Join-Path $ReleaseDir $INSTALL_NAME) + } + + Pop-Location + } +} + +if ($SkipBuild) { + Write-Host "⏩ Skipping build..." -ForegroundColor Yellow + if ($RunningOnMacOS) { + Write-Host " Using existing binaries from previous build" -ForegroundColor Yellow + } else { + # Erstelle Platzhalter-Readme für Doc-Only Release + $ReadmeContent = @" +# HypnoScript for macOS + +This is a documentation-only release package. + +To build HypnoScript for macOS, please: +1. Clone the repository on a macOS system +2. Run: ``npm run release:macos`` + +Or download pre-built binaries from GitHub Releases. + +## Manual Build on macOS + +``````bash +# Install Rust +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh + +# Clone repository +git clone https://github.com/Kink-Development-Group/hyp-runtime.git +cd hyp-runtime + +# Build +npm run release:macos +`````` +"@ + Set-Content -Path (Join-Path $ReleaseDir "BUILD_INSTRUCTIONS.md") -Value $ReadmeContent + } +} else { + # Build completed successfully on macOS + Write-Host "✓ Build completed successfully" -ForegroundColor Green +} + +# 3. Zusätzliche Dateien kopieren +Write-Host "📄 Adding additional files..." -ForegroundColor Green + +$ReadmePath = Join-Path $ProjectRoot "README.md" +if (Test-Path $ReadmePath) { + Copy-Item $ReadmePath $ReleaseDir +} + +$LicensePath = Join-Path $ProjectRoot "LICENSE" +if (Test-Path $LicensePath) { + Copy-Item $LicensePath $ReleaseDir +} + +Set-Content -Path (Join-Path $ReleaseDir "VERSION.txt") -Value $VERSION + +# 4. Installation-Script erstellen +$InstallScript = @" +#!/bin/bash +# HypnoScript macOS Installation Script + +set -e + +INSTALL_DIR="/usr/local/bin" +BINARY_NAME="hypnoscript" + +echo "Installing HypnoScript to `$INSTALL_DIR..." + +# Check for sudo +if [ "`$EUID" -ne 0 ]; then + echo "Please run with sudo:" + echo " sudo bash install.sh" + exit 1 +fi + +# Copy binary +cp `$BINARY_NAME `$INSTALL_DIR/`$BINARY_NAME +chmod +x `$INSTALL_DIR/`$BINARY_NAME + +echo "✓ HypnoScript installed successfully!" +echo "" +echo "Run 'hypnoscript --version' to verify the installation." +"@ + +Set-Content -Path (Join-Path $ReleaseDir "install.sh") -Value $InstallScript + +# 5. TAR.GZ erstellen (immer) +if ($PackageType -eq 'tar.gz' -or $PackageType -eq 'all') { + Write-Host "📦 Creating TAR.GZ archive..." -ForegroundColor Green + + $TarOut = Join-Path $ProjectRoot "release" "$NAME-$VERSION-macos-$Architecture.tar.gz" + + Push-Location (Join-Path $ProjectRoot "release") + + if ($RunningOnMacOS -or $RunningOnLinux) { + # Native tar auf macOS/Linux + tar -czf (Split-Path -Leaf $TarOut) -C "macos-$Architecture" . + } elseif ($RunningOnWindows) { + # Windows tar (verfügbar ab Windows 10 1803) + if (Get-Command tar -ErrorAction SilentlyContinue) { + & tar -czf (Split-Path -Leaf $TarOut) -C "macos-$Architecture" . + } else { + Write-Host " ⚠ tar not found on Windows - installing 7zip or update Windows" -ForegroundColor Yellow + } + } + + Pop-Location + + # Checksum + Write-Host "🔐 Generating SHA256 checksum for tar.gz..." -ForegroundColor Green + $Hash = Get-FileHash -Path $TarOut -Algorithm SHA256 + $HashString = "$($Hash.Hash.ToLower()) $(Split-Path -Leaf $TarOut)" + Set-Content -Path "$TarOut.sha256" -Value $HashString + + Write-Host "✓ TAR.GZ: $TarOut" -ForegroundColor Green + $TarSize = (Get-Item $TarOut).Length / 1MB + Write-Host " Size: $([math]::Round($TarSize, 2)) MB" -ForegroundColor Cyan +} + +# 6. DMG erstellen (nur auf macOS) +if (($PackageType -eq 'dmg' -or $PackageType -eq 'all') -and $RunningOnMacOS) { + Write-Host "📦 Creating DMG image..." -ForegroundColor Green + + $DmgDir = Join-Path $ProjectRoot "release" "dmg-staging" + $DmgOut = Join-Path $ProjectRoot "release" "$NAME-$VERSION-macos-$Architecture.dmg" + + # DMG staging vorbereiten + if (Test-Path $DmgDir) { + Remove-Item -Recurse -Force $DmgDir + } + New-Item -ItemType Directory -Force -Path $DmgDir | Out-Null + + # Binary in staging kopieren + Copy-Item (Join-Path $ReleaseDir $INSTALL_NAME) $DmgDir + Copy-Item (Join-Path $ReleaseDir "README.md") $DmgDir -ErrorAction SilentlyContinue + Copy-Item (Join-Path $ReleaseDir "LICENSE") $DmgDir -ErrorAction SilentlyContinue + + # Symlink zu /usr/local/bin erstellen + Push-Location $DmgDir + New-Item -ItemType SymbolicLink -Name "Install to /usr/local/bin" -Target "/usr/local/bin" -ErrorAction SilentlyContinue + Pop-Location + + # DMG erstellen + & hdiutil create -volname "$NAME $VERSION" ` + -srcfolder $DmgDir ` + -ov -format UDZO ` + $DmgOut + + # Cleanup + Remove-Item -Recurse -Force $DmgDir + + # Checksum + Write-Host "🔐 Generating SHA256 checksum for dmg..." -ForegroundColor Green + $Hash = Get-FileHash -Path $DmgOut -Algorithm SHA256 + $HashString = "$($Hash.Hash.ToLower()) $(Split-Path -Leaf $DmgOut)" + Set-Content -Path "$DmgOut.sha256" -Value $HashString + + Write-Host "✓ DMG: $DmgOut" -ForegroundColor Green + $DmgSize = (Get-Item $DmgOut).Length / 1MB + Write-Host " Size: $([math]::Round($DmgSize, 2)) MB" -ForegroundColor Cyan + +} elseif (($PackageType -eq 'dmg' -or $PackageType -eq 'all') -and -not $RunningOnMacOS) { + Write-Host "⚠ DMG creation requires macOS - skipped" -ForegroundColor Yellow +} + +# 7. PKG erstellen (nur auf macOS) +if (($PackageType -eq 'pkg' -or $PackageType -eq 'all') -and $RunningOnMacOS) { + Write-Host "📦 Creating PKG installer..." -ForegroundColor Green + + $PkgDir = Join-Path $ProjectRoot "release" "pkg-staging" + $PkgRoot = Join-Path $PkgDir "root" + $PkgScripts = Join-Path $PkgDir "scripts" + $PkgOut = Join-Path $ProjectRoot "release" "$NAME-$VERSION-macos-$Architecture.pkg" + + # PKG staging vorbereiten + if (Test-Path $PkgDir) { + Remove-Item -Recurse -Force $PkgDir + } + New-Item -ItemType Directory -Force -Path $PkgRoot | Out-Null + New-Item -ItemType Directory -Force -Path (Join-Path $PkgRoot "usr" "local" "bin") | Out-Null + New-Item -ItemType Directory -Force -Path $PkgScripts | Out-Null + + # Binary in staging kopieren + Copy-Item (Join-Path $ReleaseDir $INSTALL_NAME) (Join-Path $PkgRoot "usr" "local" "bin" $INSTALL_NAME) + + # Postinstall script + $PostInstall = @" +#!/bin/bash +chmod +x /usr/local/bin/$INSTALL_NAME +echo "HypnoScript installed to /usr/local/bin/$INSTALL_NAME" +exit 0 +"@ + Set-Content -Path (Join-Path $PkgScripts "postinstall") -Value $PostInstall + chmod +x (Join-Path $PkgScripts "postinstall") + + # PKG erstellen + & pkgbuild --root $PkgRoot ` + --scripts $PkgScripts ` + --identifier $BUNDLE_ID ` + --version $VERSION ` + --install-location "/" ` + $PkgOut + + # Cleanup + Remove-Item -Recurse -Force $PkgDir + + # Checksum + Write-Host "🔐 Generating SHA256 checksum for pkg..." -ForegroundColor Green + $Hash = Get-FileHash -Path $PkgOut -Algorithm SHA256 + $HashString = "$($Hash.Hash.ToLower()) $(Split-Path -Leaf $PkgOut)" + Set-Content -Path "$PkgOut.sha256" -Value $HashString + + Write-Host "✓ PKG: $PkgOut" -ForegroundColor Green + $PkgSize = (Get-Item $PkgOut).Length / 1MB + Write-Host " Size: $([math]::Round($PkgSize, 2)) MB" -ForegroundColor Cyan + +} elseif (($PackageType -eq 'pkg' -or $PackageType -eq 'all') -and -not $RunningOnMacOS) { + Write-Host "⚠ PKG creation requires macOS - skipped" -ForegroundColor Yellow +} + +# 8. Zusammenfassung +Write-Host "" +Write-Host "=== Build Summary ===" -ForegroundColor Cyan +Write-Host "Architecture: $Architecture" -ForegroundColor Yellow +Write-Host "Binary Location: $(Join-Path $ReleaseDir $INSTALL_NAME)" -ForegroundColor Cyan + +if (Test-Path (Join-Path $ProjectRoot "release" "$NAME-$VERSION-macos-$Architecture.tar.gz")) { + Write-Host "TAR.GZ: $(Join-Path $ProjectRoot "release" "$NAME-$VERSION-macos-$Architecture.tar.gz")" -ForegroundColor Cyan +} + +if (Test-Path (Join-Path $ProjectRoot "release" "$NAME-$VERSION-macos-$Architecture.dmg")) { + Write-Host "DMG: $(Join-Path $ProjectRoot "release" "$NAME-$VERSION-macos-$Architecture.dmg")" -ForegroundColor Cyan +} + +if (Test-Path (Join-Path $ProjectRoot "release" "$NAME-$VERSION-macos-$Architecture.pkg")) { + Write-Host "PKG: $(Join-Path $ProjectRoot "release" "$NAME-$VERSION-macos-$Architecture.pkg")" -ForegroundColor Cyan +} + +Write-Host "" +Write-Host "Installation instructions:" -ForegroundColor Yellow + +if ($PackageType -eq 'tar.gz' -or $PackageType -eq 'all') { + Write-Host "" + Write-Host "From TAR.GZ:" -ForegroundColor Green + Write-Host " tar -xzf $NAME-$VERSION-macos-$Architecture.tar.gz" -ForegroundColor White + Write-Host " cd macos-$Architecture" -ForegroundColor White + Write-Host " sudo bash install.sh" -ForegroundColor White +} + +if ($RunningOnMacOS) { + if ($PackageType -eq 'dmg' -or $PackageType -eq 'all') { + Write-Host "" + Write-Host "From DMG:" -ForegroundColor Green + Write-Host " 1. Open $NAME-$VERSION-macos-$Architecture.dmg" -ForegroundColor White + Write-Host " 2. Drag $INSTALL_NAME to 'Install to /usr/local/bin'" -ForegroundColor White + } + + if ($PackageType -eq 'pkg' -or $PackageType -eq 'all') { + Write-Host "" + Write-Host "From PKG:" -ForegroundColor Green + Write-Host " sudo installer -pkg $NAME-$VERSION-macos-$Architecture.pkg -target /" -ForegroundColor White + } +} + +Write-Host "" +Write-Host "Verify installation:" -ForegroundColor Yellow +Write-Host " hypnoscript --version" -ForegroundColor White +Write-Host "" +Write-Host "✓ All done!" -ForegroundColor Green diff --git a/scripts/build_winget.ps1 b/scripts/build_winget.ps1 index ac3f631..dc2dd13 100644 --- a/scripts/build_winget.ps1 +++ b/scripts/build_winget.ps1 @@ -1,25 +1,113 @@ # build_winget.ps1 -# Erstellt ein self-contained Windows-Binary und bereitet das winget-Paket vor +# Creates a Windows release package for HypnoScript Rust Runtime +# Usage: pwsh scripts/build_winget.ps1 $ErrorActionPreference = 'Stop' -# 1. Build -Write-Host 'Baue self-contained Windows-Binary...' -dotnet publish ../HypnoScript.CLI -c Release -r win-x64 --self-contained true -p:PublishSingleFile=true -o ../publish/win +Write-Host "=== HypnoScript Windows Release Builder ===" -ForegroundColor Cyan +Write-Host "" -# 2. Optional: ZIP für winget -Write-Host 'Erstelle ZIP-Archiv für winget...' -$zipPath = '../publish/HypnoScript-windows-x64.zip' -if (Test-Path $zipPath) { Remove-Item $zipPath } -Compress-Archive -Path ../publish/win/* -DestinationPath $zipPath +# Configuration +$projectRoot = Split-Path -Parent $PSScriptRoot +$releaseDir = Join-Path $projectRoot "release" +$winDir = Join-Path $releaseDir "windows-x64" +$zipPath = Join-Path $releaseDir "HypnoScript-windows-x64.zip" -# 3. SHA256 berechnen und ins Manifest eintragen -Write-Host 'Berechne SHA256-Hash für ZIP...' +# Clean previous release +if (Test-Path $releaseDir) { + Write-Host "Cleaning previous release..." -ForegroundColor Yellow + Remove-Item $releaseDir -Recurse -Force +} + +# Create release directory +New-Item -ItemType Directory -Path $winDir -Force | Out-Null + +# Build release binary +Write-Host "Building release binary for Windows x64..." -ForegroundColor Green +Push-Location $projectRoot +try { + cargo build --release --package hypnoscript-cli + + if ($LASTEXITCODE -ne 0) { + throw "Cargo build failed with exit code $LASTEXITCODE" + } +} finally { + Pop-Location +} + +# Copy binary to release directory +$binarySource = Join-Path $projectRoot "target\release\hypnoscript-cli.exe" + +if (-not (Test-Path $binarySource)) { + throw "Could not find compiled binary at $binarySource" +} + +Write-Host "Copying binary to release directory..." -ForegroundColor Green +Copy-Item $binarySource -Destination (Join-Path $winDir "hypnoscript.exe") + +# Copy additional files +Write-Host "Copying additional files..." -ForegroundColor Green + +$readmePath = Join-Path $projectRoot "README.md" +if (Test-Path $readmePath) { + Copy-Item $readmePath -Destination $winDir +} + +$licensePath = Join-Path $projectRoot "LICENSE" +if (Test-Path $licensePath) { + Copy-Item $licensePath -Destination $winDir +} + +# Create VERSION file +$version = "1.0.0-rc1" +$versionFile = Join-Path $winDir "VERSION.txt" +Set-Content -Path $versionFile -Value "HypnoScript Runtime v$version`nRust Edition`nBuilt: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" + +# Create ZIP archive +Write-Host "Creating ZIP archive..." -ForegroundColor Green +if (Test-Path $zipPath) { + Remove-Item $zipPath -Force +} + +Compress-Archive -Path "$winDir\*" -DestinationPath $zipPath -CompressionLevel Optimal + +# Calculate SHA256 hash +Write-Host "Calculating SHA256 hash..." -ForegroundColor Green $sha256 = (Get-FileHash $zipPath -Algorithm SHA256).Hash -$manifestPath = 'winget-manifest.yaml' -$manifestContent = Get-Content $manifestPath -$updatedContent = $manifestContent -replace '(InstallerSha256: ).*', "`$1$sha256" -$updatedContent | Set-Content $manifestPath -Write-Host "SHA256 ($sha256) wurde ins Manifest eingetragen." +Write-Host "SHA256: $sha256" -ForegroundColor Yellow + +# Update manifest if it exists +$manifestPath = Join-Path $PSScriptRoot "winget-manifest.yaml" +if (Test-Path $manifestPath) { + Write-Host "Updating winget manifest..." -ForegroundColor Green + $manifestContent = Get-Content $manifestPath -Raw + $manifestContent = $manifestContent -replace '(InstallerSha256:\s*)([a-fA-F0-9]+)', "`${1}$sha256" + Set-Content -Path $manifestPath -Value $manifestContent -NoNewline + Write-Host "Manifest updated with new SHA256 hash" -ForegroundColor Green +} + +# Display summary +Write-Host "" +Write-Host "=== Build Summary ===" -ForegroundColor Cyan +Write-Host "Release Directory: $releaseDir" -ForegroundColor White +Write-Host "Binary Location: $(Join-Path $winDir 'hypnoscript.exe')" -ForegroundColor White +Write-Host "ZIP Archive: $zipPath" -ForegroundColor White +Write-Host "SHA256 Hash: $sha256" -ForegroundColor White +Write-Host "" + +# Get file sizes +$binarySize = [math]::Round((Get-Item (Join-Path $winDir "hypnoscript.exe")).Length / 1MB, 2) +$zipSize = [math]::Round((Get-Item $zipPath).Length / 1MB, 2) + +Write-Host "Binary Size: $binarySize MB" -ForegroundColor White +Write-Host "Archive Size: $zipSize MB" -ForegroundColor White +Write-Host "" +Write-Host "✓ Windows release package created successfully!" -ForegroundColor Green +Write-Host "" -Write-Host 'Fertig! Release liegt in ../publish/win und als ZIP vor.' +# Test the binary +Write-Host "=== Testing Binary ===" -ForegroundColor Cyan +$testBinary = Join-Path $winDir "hypnoscript.exe" +& $testBinary version +Write-Host "" +Write-Host "✓ All done!" -ForegroundColor Green