diff --git a/.claude/skills/update-axsharp-version/SKILL.md b/.claude/skills/update-axsharp-version/SKILL.md new file mode 100644 index 000000000..3cfc27e2d --- /dev/null +++ b/.claude/skills/update-axsharp-version/SKILL.md @@ -0,0 +1,167 @@ +--- +name: update-axsharp-version +description: Update AXSharp.* and Inxton.Operon.* package versions in this repo (via scripts/update_axsharp_versions.ps1), verify the build, update the central CHANGELOG.md, and open a PR with a generated description. Use when the user asks to bump/update AXSharp versions or open a dependency-update PR. Defaults to the latest versions from the feed; accepts optional explicit versions. +--- + +# Update AXSharp version + +Drives the AXSharp / Inxton.Operon dependency bump end to end: run the existing update script → +verify the build → record the change in the central `CHANGELOG.md` → open a PR. + +The actual file edits live in [`scripts/update_axsharp_versions.ps1`](../../../scripts/update_axsharp_versions.ps1). +**Do not reimplement version rewriting** — this skill only orchestrates around that script. + +By default the script auto-detects the latest `AXSharp.ixc` and `Inxton.Operon` versions from the +GitHub Packages feed. The user may pass explicit versions; thread them through as +`-AxSharpVersion ` / `-OperonVersion ` on every script invocation below. + +## Procedure + +### 1. Preconditions + +- Run all commands from the **repo root**. The script resolves its own `repoRoot`, but `git`/`gh` + operations assume root. +- **Token (auto-detect mode only):** the script needs a feed token with `read:packages` scope. It + reads, in order, `AXSHARP_FEED_TOKEN`, `GITHUB_PACKAGES_TOKEN`, `GITHUB_TOKEN`, `GH_TOKEN`, + `NUGET_TOKEN`. If none is set **and** no explicit versions were given, tell the user to set one + (or pass `-Token`) and stop. Skip this check when explicit versions are supplied. +- **Clean tree:** run `git status`. If the working tree is dirty, surface it and stop — do not bundle + unrelated changes into a dependency PR. + +### 2. Branch + +Check the current branch (`git branch --show-current`). If on the default branch `dev` (or any +protected branch), create a working branch first. Prefer a version-tagged name once the version is +known, otherwise a generic one: + +```powershell +git switch -c chore/update-axsharp-versions +``` + +If already on a non-default working branch, stay on it. + +### 3. Preview (recommended) + +Show the user what will change before touching files: + +```powershell +pwsh -File scripts/update_axsharp_versions.ps1 -DryRun -Detailed +``` + +Append `-AxSharpVersion -OperonVersion ` to override. Use `-ListAvailable` to inspect feed +versions. The dry run must not modify files — `git status` stays clean. + +### 4. Apply + +Run for real and **capture stdout** — the `Summary of changes:` and `Target versions:` blocks feed +the CHANGELOG entry, commit message, and PR body: + +```powershell +pwsh -File scripts/update_axsharp_versions.ps1 +# or, with overrides: +pwsh -File scripts/update_axsharp_versions.ps1 -AxSharpVersion -OperonVersion +``` + +Handle outcomes: +- **Non-zero exit** — exit `2` = feed/auth failure, exit `3` = JSON parse failure. Report the error + output and stop. +- **No changes** — if `git status` shows nothing changed, report "already up to date at + ``" and stop. Do **not** open a PR. + +Record the resolved `` and `` from the script's `Target versions:` +block for the steps below. + +### 5. Verify build + +Confirm the new package set resolves before opening the PR (build only, no tests): + +```powershell +dotnet run --project cake/Build.csproj -- --do-apax-update +``` + +`--do-apax-update` pulls the apax-side packages; the .NET restore covers the central-managed NuGet +bumps. For a heavier check, [`scripts/build_with_update.ps1`](../../../scripts/build_with_update.ps1) +runs build + tests at level 10. + +If the build **fails**: report the failure with output and **do not open the PR**. Leave the changes +on the branch for the user to inspect. + +### 6. Update central CHANGELOG.md + +Prepend a new entry at the **top** of [`CHANGELOG.md`](../../../CHANGELOG.md) (newest-on-top, above +the current first `###` heading), matching the existing structured format. Use category tag `[DEPS]`. +Fill bullets from the script's `Summary of changes:` block. + +```markdown +### [DEPS] Update AXSharp / Inxton.Operon package versions to + +**Note:** Dependency version bump via `scripts/update_axsharp_versions.ps1`. No source change. +Branch: ``. + +- chore: AXSharp.* packages updated to `` in `.config/dotnet-tools.json` and `Directory.Packages.props`. +- chore: Inxton.Operon.* packages updated to ``. +- chore: reconciled AXSharp transitive (third-party) dependencies in `Directory.Packages.props` (bump-up only). + + +**Impact:** +- Repo now builds and tests against AXSharp `` / Inxton.Operon ``. + +**Risks/Review:** +- Transitive pinned versions were bumped up to satisfy AXSharp's nuspec requirements; review `Directory.Packages.props` diff. + +**Testing:** +- `dotnet run --project cake/Build.csproj -- --do-apax-update` — build succeeds with the new package set. +``` + +### 7. Commit + +Match the repo convention (see commit `0929211f1`): + +```powershell +git add .config/dotnet-tools.json Directory.Packages.props CHANGELOG.md +git commit -m "chore: update AXSharp package versions to and reconcile transitive dependencies" +git push -u origin HEAD +``` + +Scope the `git add` to the touched files. (The script edits only these in a normal run.) + +### 8. Create PR + +```powershell +gh pr create --base dev --title "chore: update AXSharp package versions to " --body "" +``` + +Use the template below for ``, filling placeholders and pasting the script's +`Summary of changes:` lines as a bullet list. Report the resulting PR URL to the user. + +#### PR body template + +```markdown +## Update AXSharp / Inxton.Operon package versions + +Bumps AXSharp.* and Inxton.Operon.* packages and reconciles transitive (third-party) dependencies +that AXSharp requires, via `scripts/update_axsharp_versions.ps1`. + +### Target versions +- **AXSharp.\***: `` +- **Inxton.Operon.\***: `` + +### Changes +- `.config/dotnet-tools.json` — tool versions bumped +- `Directory.Packages.props` — package versions + bump-up of pinned transitive deps +- `CHANGELOG.md` — `[DEPS]` entry prepended + + + +### Verification +- [x] `dotnet run --project cake/Build.csproj -- --do-apax-update` succeeded + +🤖 Generated with [Claude Code](https://claude.com/claude-code) +``` + +## Notes + +- Script switches: `-DryRun`, `-Detailed`, `-ListAvailable`, `-AxSharpVersion`, `-OperonVersion`, + `-SkipTransitive`, `-Source`, `-Token`, `-Username`, `-NormalizeJson`. +- Default PR base branch: `dev`. +- Build options live in [`cake/BuildParameters.cs`](../../../cake/BuildParameters.cs). diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index d91096d5a..d48523e89 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "AXSharp.ixc": { - "version": "0.47.0-alpha.479", + "version": "0.47.0-alpha.484", "commands": [ "ixc" ], @@ -17,14 +17,14 @@ "rollForward": false }, "AXSharp.ixd": { - "version": "0.47.0-alpha.479", + "version": "0.47.0-alpha.484", "commands": [ "ixd" ], "rollForward": false }, "AXSharp.ixr": { - "version": "0.47.0-alpha.479", + "version": "0.47.0-alpha.484", "commands": [ "ixr" ], diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index cee3d166c..6cd271afe 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -91,7 +91,7 @@ jobs: GH_TOKEN : ${{ secrets.GH_TOKEN }} GH_USER : ${{ secrets.GH_USER }} run: | - dotnet run --project cake/Build.csproj --apps-run + dotnet run --project cake/Build.csproj --do-test --test-level 4 "TEST_EXIT_CODE=$LASTEXITCODE" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 shell: pwsh diff --git a/.github/workflows/single_app_run.yml b/.github/workflows/single_app_run.yml deleted file mode 100644 index dd2d2fb88..000000000 --- a/.github/workflows/single_app_run.yml +++ /dev/null @@ -1,127 +0,0 @@ -name: single_app_run -permissions: - contents: read -on: - workflow_dispatch: - inputs: - folder: - description: "Select library folder" - required: true - default: "template.axolibrary" - type: choice - options: - - abstractions - - components.abb.robotics - - components.abstractions - - components.balluff.identification - - components.cognex.vision - - components.desoutter.tightening - - components.drives - - components.elements - - components.festo.drives - - components.kuka.robotics - - components.keyence.vision - - components.mitsubishi.robotics - - components.pneumatics - - components.rexroth.drives - - components.rexroth.press - - components.robotics - - components.siem.identification - - components.ur.robotics - - core - - data - - inspectors - - integrations - - io - - probers - - simatic1500 - - template.axolibrary - - timers - - utils - -jobs: - app-run-manual-with-selected-folder: - runs-on: [self-hosted, Windows, X64, L3, AX, APP] - steps: - - name: Checkout - uses: actions/checkout@v3 - with: - fetch-depth: '0' - - - name: Get Branch Name - run: | - if ($env:GITHUB_REF -like "refs/pull/*") { - $BRANCH_NAME = "${{ github.event.pull_request.head.ref }}" - } else { - $BRANCH_NAME = $env:GITHUB_REF -replace 'refs/heads/', '' - } - Write-Host "Triggered on branch: $BRANCH_NAME" - "BRANCH_NAME=$BRANCH_NAME" | Out-File -FilePath $env:GITHUB_ENV -Append - shell: pwsh - - - name: Get Short Commit SHA - run: | - $currentSHA = git rev-parse --short HEAD - "CURRENT_SHA=$currentSHA" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 - shell: pwsh - - - name: Setup - run: | - "TEST_EXIT_CODE=123" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 - shell: pwsh - - - name: Print and store library folder - run: | - $APP_FOLDER = "${{ inputs.folder }}" - Write-Host "Selected folder: $APP_FOLDER" - "APP_FOLDER=$APP_FOLDER" | Out-File -FilePath $env:GITHUB_ENV -Append - shell: pwsh - - - name: "Build cake" - run: dotnet build cake/Build.csproj - shell: pwsh - - - name: "Run cake with single app" - continue-on-error: true - env: - GH_TOKEN : ${{ secrets.GH_TOKEN }} - GH_USER : ${{ secrets.GH_USER }} - run: | - dotnet run --project cake/Build.csproj --skip-build --apps-run --single-app-run-folder-name $env:APP_FOLDER - "TEST_EXIT_CODE=$LASTEXITCODE" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 - shell: pwsh - - - name: Display workflow details in Summary - run: | - if($env:TEST_EXIT_CODE -eq "123") - { - $TEST_RESULT = "SKIPPED" - } - elseif($env:TEST_EXIT_CODE -eq "0") - { - $TEST_RESULT = "PASSED" - } - else - { - $TEST_RESULT = "FAILED" - } - "### Runner name: $env:RUNNER_NAME ::: Branch name: $env:BRANCH_NAME ::: Library folder: $env:APP_FOLDER ::: Commit SHA: $env:CURRENT_SHA ::: Test result: $TEST_RESULT" | Out-File -FilePath $env:GITHUB_STEP_SUMMARY -Append -Encoding utf8 - shell: pwsh - - - name: Evaluate final result - run: | - if($env:TEST_EXIT_CODE -eq "123") - { - echo "Tests skipped." - } - elseif($env:TEST_EXIT_CODE -eq "0") - { - echo "Tests passed." - } - else - { - echo "Tests failed." - Exit 1 - } - shell: pwsh - diff --git a/.gitignore b/.gitignore index 6188d277e..cb9410427 100644 --- a/.gitignore +++ b/.gitignore @@ -439,3 +439,6 @@ operon-variables.css **/app/gsd/source/** *.lscache + +# Vulnerability scan reports (scripts/update-vulnerable-deps.ps1) +scripts/reports/ diff --git a/CHANGELOG.md b/CHANGELOG.md index b8654c355..ea863b69f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,27 @@ +### [BUILD] Dependency-maintenance tooling + AXSharp `0.47.0-alpha.484` bump + +**Note:** Build/CI tooling and dependency maintenance. No public-API change, no PLC source change. Branch: `deps-update`. + +- feat: `scripts/update-latest-deps.ps1` — bumps all non-AXSharp dependencies (NuGet + npm) to their latest stable versions, sharing common helpers via `scripts/_deps-common.ps1`. +- feat: `scripts/update-vulnerable-deps.ps1` — scans npm and NuGet dependencies for known vulnerabilities and emits a report. +- chore: AXSharp packages bumped to `0.47.0-alpha.484` in `Directory.Packages.props`, with transitive dependencies reconciled. `.config/dotnet-tools.json` updated to match. +- chore: Added `.claude/skills/update-axsharp-version/SKILL.md` — skill for updating AXSharp and Inxton.Operon package versions. +- chore: Removed obsolete `package.json` / `package-lock.json` files across `src/components.abb.robotics`, `src/components.abstractions`, `src/data`, `src/data/src/AXOpen.Data.Blazor`, `src/inspectors`, and a stray `apax.yml`, to clean up the project structure. +- chore: `develop` branch GitVersion mode changed to `ContinuousDeployment`. +- chore: Styling dependencies refreshed (`src/styling/src/package.json` / lock; `momentum.css` regenerated). + +**Impact:** +- Routine dependency bumps and vulnerability scanning are now scriptable and reproducible. +- AXSharp consumers build against `0.47.0-alpha.484`. +- Dead npm lockfiles no longer pollute the tree or trigger spurious tooling. + +**Risks/Review:** +- Dependency version bumps can introduce behavioural drift; verify a full `dotnet build` and the styling render after pulling. + +**Testing:** +- Run `scripts/update-latest-deps.ps1` and `scripts/update-vulnerable-deps.ps1` end-to-end (exit code 0). +- `dotnet build` from solution root succeeds against the bumped package set. + ### [CORE] AxoSequencer step-timeout alarm — does not fall after timeout clears **Note:** PLC bug fix in `src/core/ctrl/src/AxoCoordination/AxoSequencer/AxoSequencer.st` (`AxoStepTimedOutMessenger.Activate`). No public-API change. Branch: `fix-issue-when-timeout-sequencer-alarm-doesnot-fall`. diff --git a/Directory.Packages.props b/Directory.Packages.props index b0b218dc6..73c8c8c39 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -11,12 +11,12 @@ - - - - - - + + + + + + @@ -24,7 +24,7 @@ - + @@ -88,15 +88,10 @@ - - - - - - - - - - - - + + + + + + + \ No newline at end of file diff --git a/GitVersion.yml b/GitVersion.yml index ef800d38e..458569c2d 100644 --- a/GitVersion.yml +++ b/GitVersion.yml @@ -1,5 +1,5 @@ mode: ContinuousDeployment -next-version: 0.56.3 +next-version: 0.56.4 branches: main: regex: ^master$|^main$ @@ -15,7 +15,7 @@ branches: pre-release-weight: 55000 develop: regex: ^dev(elop)?(ment)?$ - mode: ManualDeployment + mode: ContinuousDeployment label: alpha increment: Minor prevent-increment: diff --git a/cake/AppsRunTaskHelpers.cs b/cake/AppsRunTaskHelpers.cs index c1a9bd7cd..cb9a0ae81 100644 --- a/cake/AppsRunTaskHelpers.cs +++ b/cake/AppsRunTaskHelpers.cs @@ -1,4 +1,4 @@ -using Cake.Common.Diagnostics; +using Cake.Common.Diagnostics; using Cake.Common.IO; using Cake.Core.Diagnostics; using System; @@ -17,276 +17,110 @@ internal static class AppsRunTaskHelpers { - - public static void BuildAndLoadPlc(BuildContext context, string appYamlFile, string appName, string logFilePath, ref bool summaryResult) + /// + /// Test level 4 integration step: loads the entire showcase PLC (incl. hardware configuration) onto + /// PLCSIM Advanced, starts the Blazor server and asserts it serves traffic over HTTPS. + /// Fails the build (non-zero exit) on any error and always cleans up the spawned processes. + /// + public static void RunShowcaseIntegration(BuildContext context, string appYamlFile) { - string plcName = context.PlcName; - string plcIpAddress = context.PlcIpAddress; - - // Validate application YAML file - if (string.IsNullOrWhiteSpace(appYamlFile)) - { - context.Log.Error("The provided YAML of the application is empty."); - return; - } - - if (!File.Exists(appYamlFile)) - { - context.Log.Error($"The provided application file does not exist: {appYamlFile}"); - return; - } - - if (string.IsNullOrWhiteSpace(appName)) - { - context.Log.Error("The provided application name is empty."); - return; - } - - string appFolder = Path.GetDirectoryName(appYamlFile); - if (string.IsNullOrWhiteSpace(appFolder) || !Directory.Exists(appFolder)) - { - context.Log.Error($"The provided path for the application does not exist: {appFolder}"); - return; - } - - // Run "apax install" - ApaxCmd.ApaxInstall(context, appFolder); - - // Run "apax plcsim" - string plcSimResult = ApaxCmd.ApaxPlcSim(context, appFolder, ref summaryResult); - WriteResult(context, plcSimResult, logFilePath, appendToSameLine: true); - - // Run "apax hwu" - string hwuResult = ApaxCmd.ApaxHwu(context, appFolder, ref summaryResult); - WriteResult(context, hwuResult, logFilePath, appendToSameLine: true); - - // Run "apax swfd" - string swfdResult = ApaxCmd.ApaxSwfd(context, appFolder, ref summaryResult); - WriteResult(context, swfdResult, logFilePath, appendToSameLine: true); - } - public static void AppRunDetailed(BuildContext context, string appYamlFile, string appName, string logFilePath, ref bool summaryResult) - { - string plcName = context.PlcName; - string plcIpAddress = context.PlcIpAddress; - - // Validate application YAML file - if (string.IsNullOrWhiteSpace(appYamlFile)) - { - context.Log.Error("The provided YAML of the application is empty."); - return; - } + bool summaryResult = true; - if (!File.Exists(appYamlFile)) + if (string.IsNullOrWhiteSpace(appYamlFile) || !File.Exists(appYamlFile)) { - context.Log.Error($"The provided application file does not exist: {appYamlFile}"); + context.Log.Error($"Showcase application file does not exist: {appYamlFile}"); + Environment.Exit(1); return; } - if (string.IsNullOrWhiteSpace(appName)) - { - context.Log.Error("The provided application name is empty."); - return; - } - - string appFolder = Path.GetDirectoryName(appYamlFile); - if (string.IsNullOrWhiteSpace(appFolder) || !Directory.Exists(appFolder)) - { - context.Log.Error($"The provided path for the application does not exist: {appFolder}"); - return; - } - - // Run "apax install" - string result = ApaxCmd.ApaxCommand(context, appFolder, "install", ref summaryResult); - WriteResult(context, result, logFilePath, appendToSameLine: true); - - // Run "apax plcsim" - result = ApaxCmd.ApaxPlcSim(context, appFolder, ref summaryResult); - WriteResult(context, result, logFilePath, appendToSameLine: true); - - // Run "apax gsd" # copy and install all gsdml files from libraries - result = ApaxCmd.ApaxCommand(context, appFolder, "gsd", ref summaryResult); - WriteResult(context, result, logFilePath, appendToSameLine: true); - - // Run "apax hwl" # copy all templates from libraries - result = ApaxCmd.ApaxCommand(context, appFolder, "hwl", ref summaryResult); - WriteResult(context, result, logFilePath, appendToSameLine: true); - - // Run "apax hwcc" # compile hardware configuration - result = ApaxCmd.ApaxCommand(context, appFolder, "hwcc", ref summaryResult); - WriteResult(context, result, logFilePath, appendToSameLine: true); - - // Run "apax hwid" # copy the generated HwIds from global constants into the type definition, matching the format as the TIA2AX tool creates - result = ApaxCmd.ApaxCommand(context, appFolder, "hwid", ref summaryResult); - WriteResult(context, result, logFilePath, appendToSameLine: true); - - // Run "apax hwadr" # copy the generated IoAddresses - result = ApaxCmd.ApaxCommand(context, appFolder, "hwadr", ref summaryResult); - WriteResult(context, result, logFilePath, appendToSameLine: true); - - // Run "apax hwdo" # download HW only using certificate - result = ApaxCmd.ApaxCommand(context, appFolder, "hwdo", ref summaryResult); - WriteResult(context, result, logFilePath, appendToSameLine: true); - - // Run "apax build " - result = ApaxCmd.ApaxCommand(context, appFolder, "build", ref summaryResult); - WriteResult(context, result, logFilePath, appendToSameLine: true); - - // Run "dotnet ixc" - result = DotNetCmd.DotNetIxc(context, appFolder, ref summaryResult); - WriteResult(context, result, logFilePath, appendToSameLine: true); - - // Run "apax swfdo" # software full download only - result = ApaxCmd.ApaxCommand(context, appFolder, "swfdo", ref summaryResult); - WriteResult(context, result, logFilePath, appendToSameLine: true); - + string appFolder = Path.GetFullPath(Path.GetDirectoryName(appYamlFile)); + string appName = context.GetApplicationName(appYamlFile); - // Recreate solution file by running the slngen script - string slnGenPath = Path.GetFullPath(Path.GetFullPath(Path.Combine(appFolder, "..", "./slngen.ps1"))); - result = DotNetCmd.RunPowershellScript(context, slnGenPath, "", ref summaryResult); - WriteResult(context, result, logFilePath, appendToSameLine: true); + context.Log.Information("###################################################"); + context.Log.Information($"Test level 4 showcase integration: {appName}"); + context.Log.Information($"Application file: {appYamlFile}"); + context.Log.Information("###################################################"); - // Clean solution - string solutionFile = Path.GetFullPath(Path.Combine(appFolder, "../this.sln")); - result = DotNetCmd.DotNetClean(context, solutionFile, "-c Debug", ref summaryResult); - WriteResult(context, result, logFilePath, appendToSameLine: true); + // Make sure no stale simulator UI is running before we start. + KillProcess(context, "Siemens.Simatic.PlcSim.Advanced.UserInterface"); - //########################## template.axolibrary => ######################// - if (appFolder.Contains("template.axolibrary")) + try { - string dot_g_folder = Path.GetFullPath(Path.Combine(appFolder, "ix//.g")); - context.CleanDirectory(dot_g_folder, new CleanDirectorySettings() { Force = true }); - - string dot_meta_folder = Path.GetFullPath(Path.Combine(appFolder, "ix//.meta")); - context.CleanDirectory(dot_meta_folder, new CleanDirectorySettings() { Force = true }); - - // Run "dotnet ixc" - result = DotNetCmd.DotNetIxc(context, appFolder, ref summaryResult); - } - - //########################## <= template.axolibrary ######################// + // Clean state from previous runs. + DeleteJsonReposFolder(context, appFolder); - //// Build solution - //result = DotNetCmd.DotNetBuildWithResult(context, solutionFile, "-c Debug", ref summaryResult); - //WriteResult(context, result, logFilePath, appendToSameLine: true); + // Prepare a fresh PLCSIM Advanced virtual memory card instance. + InitializePlcSimInstance(context, appName); - //// Get blazor projects - //var blazorFiles = Directory.GetFiles(appFolder, "*.csproj", SearchOption.AllDirectories).Where(file => file.Contains("blazor")).ToList(); + // Provide the certificate / security configuration used by the secure download. + OverwriteSecurityFiles(context, appYamlFile, context.PlcName); - // Get blazor projects - var blazorFiles = Directory.GetFiles(appFolder, "*.csproj", SearchOption.AllDirectories).Where(file => file.Contains("blazor")).ToList(); + // Full first-download of hardware + software onto the simulator. + LoadShowcasePlc(context, appFolder, ref summaryResult); - if (blazorFiles.Any()) - { - foreach (var blazorFile in blazorFiles) + if (!summaryResult) { - // Build solution - result = DotNetCmd.DotNetBuildWithResult(context, blazorFile, "-c Debug", ref summaryResult); - WriteResult(context, result, logFilePath, appendToSameLine: true); - - context.Log.Information($"Application 'blazor' file: {blazorFile}"); + context.Log.Error("Showcase PLC load failed."); + } + else + { + // Build and run the Blazor server, then probe it over HTTPS. + var blazorFile = Directory + .GetFiles(appFolder, "*.csproj", SearchOption.AllDirectories) + .FirstOrDefault(file => file.Contains("blazor") && !File.ReadAllText(file).Contains("")); - // Filter out libraries by checking for in the project file - string csprojContent = File.ReadAllText(blazorFile); - if (!csprojContent.Contains("")) + if (string.IsNullOrEmpty(blazorFile)) { - result = DotNetCmd.DotNetRunWithResult(context, blazorFile, "-c Debug --framework net9.0", 60, ref summaryResult); - WriteResult(context, result, logFilePath, appendToSameLine: true); + context.Log.Error("No runnable Blazor project (*blazor*.csproj without ) was found."); + summaryResult = false; + } + else + { + DotNetCmd.DotNetBuildWithResult(context, blazorFile, "-c Debug", ref summaryResult); + + DotNetCmd.DotNetRunWithHealthCheck( + context, + blazorFile, + "-c Debug --launch-profile https", + "https://localhost:7290", + 120, + ref summaryResult); } } } - else - { - context.Log.Information("No files containing 'blazor' in the filename and ending with '.csproj' were found."); - } - } - - public static void BuildAndStartHmi(BuildContext context, string appYamlFile, string appName, string logFilePath, ref bool summaryResult) - { - // Validate application YAML file - if (string.IsNullOrWhiteSpace(appYamlFile)) - { - context.Log.Error("The provided YAML of the application is empty."); - return; - } - - if (!context.FileExists(appYamlFile)) - { - context.Log.Error($"The provided application file does not exist: {appYamlFile}"); - return; - } - - if (string.IsNullOrWhiteSpace(appName)) - { - context.Log.Error("The provided application name is empty."); - return; - } - - string appFolder = Path.GetFullPath(Path.GetDirectoryName(appYamlFile)); - if (string.IsNullOrWhiteSpace(appFolder) || !context.DirectoryExists(appFolder)) + finally { - context.Log.Error($"The provided path for the application does not exist: {appFolder}"); - return; + // Always tear down the Blazor server and the simulator, even on success. + KillProcess(context, "dotnet"); + KillProcess(context, "Siemens.Simatic.PlcSim.Advanced.UserInterface"); } - // Recreate solution file by running the slngen script - string slnGenPath = Path.GetFullPath(Path.GetFullPath(Path.Combine(appFolder, "..", "./slngen.ps1"))); - DotNetCmd.RunPowershellScript(context, slnGenPath, ""); - - // Clean solution - string solutionFile = Path.GetFullPath(Path.Combine(appFolder, "../this.sln")); - DotNetCmd.DotNetClean(context, solutionFile, "-c Debug"); - - - //########################## template.axolibrary => ######################// - if (appFolder.Contains("template.axolibrary")) + if (!summaryResult) { - string dot_g_folder = Path.GetFullPath(Path.Combine(appFolder, "ix//.g")); - context.CleanDirectory(dot_g_folder, new CleanDirectorySettings() { Force = true }); - - string dot_meta_folder = Path.GetFullPath(Path.Combine(appFolder, "ix//.meta")); - context.CleanDirectory(dot_meta_folder, new CleanDirectorySettings() { Force = true }); - - // Run "dotnet ixc" - DotNetCmd.DotNetIxc(context, appFolder, ref summaryResult); + context.Log.Error("Showcase integration (test level 4) failed."); + Environment.Exit(1); } - //########################## <= template.axolibrary ######################// - - //// Build solution - //string buildResult = DotNetCmd.DotNetBuildWithResult(context, solutionFile, "-c Debug", ref summaryResult); - //WriteResult(context, buildResult, logFilePath, appendToSameLine: true); - - //// Get blazor projects - //var blazorFiles = Directory.GetFiles(appFolder, "*.csproj", SearchOption.AllDirectories).Where(file => file.Contains("blazor")).ToList(); - - // Get blazor projects - var blazorFiles = Directory.GetFiles(appFolder, "*.csproj", SearchOption.AllDirectories).Where(file => file.Contains("blazor")).ToList(); - - - - if (blazorFiles.Any()) - { - foreach (var blazorFile in blazorFiles) - { - // Build solution - string buildResult = DotNetCmd.DotNetBuildWithResult(context, blazorFile, "-c Debug", ref summaryResult); - WriteResult(context, buildResult, logFilePath, appendToSameLine: true); - - context.Log.Information($"Application 'blazor' file: {blazorFile}"); + context.Log.Information("Showcase integration (test level 4) done."); + } - // Filter out libraries by checking for in the project file - string csprojContent = File.ReadAllText(blazorFile); - if (!csprojContent.Contains("")) - { - string runResult = DotNetCmd.DotNetRunWithResult(context, blazorFile, "-c Debug --framework net9.0", 60, ref summaryResult); - WriteResult(context, runResult, logFilePath, appendToSameLine: true); - } - } - } - else - { - context.Log.Information("No files containing 'blazor' in the filename and ending with '.csproj' were found."); - } + /// + /// Performs the full first-download apax sequence for the showcase application onto PLCSIM Advanced: + /// install -> plcsim -> gsd -> hwl -> hwcc -> hwid -> hwadr -> hwdo -> build -> dotnet ixc -> swfdo. + /// + public static void LoadShowcasePlc(BuildContext context, string appFolder, ref bool summaryResult) + { + ApaxCmd.ApaxCommand(context, appFolder, "install", ref summaryResult); // install dependencies + ApaxCmd.ApaxPlcSim(context, appFolder, ref summaryResult); // start PLCSIM Advanced instance + ApaxCmd.ApaxCommand(context, appFolder, "gsd", ref summaryResult); // copy & install GSDML files + ApaxCmd.ApaxCommand(context, appFolder, "hwl", ref summaryResult); // copy hardware templates + ApaxCmd.ApaxCommand(context, appFolder, "hwcc", ref summaryResult); // compile hardware configuration + ApaxCmd.ApaxCommand(context, appFolder, "hwid", ref summaryResult); // copy generated HwIds + ApaxCmd.ApaxCommand(context, appFolder, "hwadr", ref summaryResult); // copy generated IO addresses + ApaxCmd.ApaxCommand(context, appFolder, "hwdo", ref summaryResult); // download hardware only + ApaxCmd.ApaxCommand(context, appFolder, "build", ref summaryResult); // compile SIMATIC AX code + DotNetCmd.DotNetIxc(context, appFolder, ref summaryResult); // generate IXC twin controller + ApaxCmd.ApaxCommand(context, appFolder, "swfdo", ref summaryResult); // software full download only } public static (bool Success, string FilePath) CreateLogFile(BuildContext context, string fileNamePrefix = "app_test_result") @@ -646,4 +480,4 @@ public static void WriteResult(BuildContext context, string textToWrite, string context.Log.Error($"An error occurred while writing to the file: {ex.Message}"); } } -} \ No newline at end of file +} diff --git a/cake/BuildParameters.cs b/cake/BuildParameters.cs index ad7f1b675..250de1689 100644 --- a/cake/BuildParameters.cs +++ b/cake/BuildParameters.cs @@ -28,7 +28,7 @@ public class BuildParameters [Option('v', "verbosity", Required = false, Default = DotNetVerbosity.Minimal, HelpText = "Verbosity (default Quiet)")] public DotNetVerbosity Verbosity { get; set; } - [Option('l', "test-level", Required = false, Default = 1, HelpText = "Test level 1 - 3")] + [Option('l', "test-level", Required = false, Default = 1, HelpText = "Test level 1 - 4")] public int TestLevel { get; set; } [Option('r', "do-publish-release", Required = false, Default = false, HelpText = "Publishes release on GH")] @@ -49,12 +49,6 @@ public class BuildParameters [Option('b', "skip-build", Required = false, Default = false, HelpText = "Does not run build steps")] public bool NoBuild { get; set; } - [Option('a', "apps-run", Required = false, Default = false, HelpText = "Download to PLC and run apps ")] - public bool AppsRun{ get; set; } - [Option('o', "do-publish-only", Required = false, Default = false, HelpText = "Skips all steps and publishes from pre-build artefacts.")] public bool PublishOnly { get; set; } - - [Option('s', "single-app-run-folder-name", Required = false, Default = "", HelpText = "Download to PLC and run just app from folder")] - public string AppRunOnlyFolderName { get; set; } } \ No newline at end of file diff --git a/cake/DotNetCmd.cs b/cake/DotNetCmd.cs index fc2d29e8c..2af679783 100644 --- a/cake/DotNetCmd.cs +++ b/cake/DotNetCmd.cs @@ -13,6 +13,7 @@ using System.IO; using System.Linq; using System.Management.Automation; +using System.Net.Http; using System.Text; using System.Threading.Tasks; using Cake.Common.IO; @@ -487,4 +488,131 @@ public static string DotNetRunWithResult(this BuildContext context, string proje return retVal; } } + + /// + /// Runs a project via "dotnet run" and probes until it returns a + /// success status code or elapses. The probe accepts self-signed + /// development certificates. The spawned process is always terminated before returning. + /// Returns ",OK" on a healthy response, ",NOK" otherwise (and sets to false). + /// + public static string DotNetRunWithHealthCheck(this BuildContext context, string projectPath, string arguments, string healthUrl, int maxWaitSeconds, ref bool summaryResult) + { + string workDir = Path.GetFullPath(Path.Combine(projectPath, "..")); + string args = $"run --project \"{projectPath}\" {arguments}"; + context.Log.Information($"Dotnet run (health check) started with project: {projectPath}"); + + string retVal = ",NOK"; + + var processStartInfo = new ProcessStartInfo + { + FileName = "dotnet", + Arguments = args, + WorkingDirectory = workDir, + RedirectStandardOutput = true, + RedirectStandardError = true, + UseShellExecute = false, + CreateNoWindow = true + }; + + using (var process = Process.Start(processStartInfo)) + { + if (process == null) + { + summaryResult = false; + throw new Exception("Failed to start the process."); + } + + // Asynchronously drain the output and error streams. + Task outputTask = Task.Run(() => + { + while (!process.StandardOutput.EndOfStream) + { + var line = process.StandardOutput.ReadLine(); + if (!string.IsNullOrEmpty(line)) + { + context.Log.Information($"[Output] {line}"); + } + } + }); + + Task errorTask = Task.Run(() => + { + while (!process.StandardError.EndOfStream) + { + var line = process.StandardError.ReadLine(); + if (!string.IsNullOrEmpty(line)) + { + context.Log.Error($"[Error] {line}"); + } + } + }); + + try + { + // Probe the server, accepting the self-signed development certificate. + using (var handler = new HttpClientHandler + { + ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator + }) + using (var client = new HttpClient(handler) { Timeout = TimeSpan.FromSeconds(5) }) + { + bool healthy = false; + int waited = 0; + + while (waited < maxWaitSeconds) + { + if (process.HasExited) + { + context.Log.Error($"The application '{projectPath}' exited before serving (exit code {process.ExitCode})."); + break; + } + + try + { + var response = client.GetAsync(healthUrl).GetAwaiter().GetResult(); + if (response.IsSuccessStatusCode) + { + context.Log.Information($"Health check OK: {healthUrl} returned {(int)response.StatusCode}."); + healthy = true; + break; + } + + context.Log.Information($"Health check: {healthUrl} returned {(int)response.StatusCode}, retrying..."); + } + catch (Exception ex) + { + context.Log.Information($"Health check: {healthUrl} not ready yet ({ex.Message}), retrying..."); + } + + Task.Delay(2000).Wait(); + waited += 2; + } + + if (healthy) + { + retVal = ",OK"; + } + else + { + summaryResult = false; + context.Log.Error($"Health check FAILED: no success response from {healthUrl} within {maxWaitSeconds}s."); + } + } + } + finally + { + // Always stop the server. + if (!process.HasExited) + { + context.Log.Information($"Terminating the application '{projectPath}'..."); + process.Kill(true); + } + + Task.WhenAll(outputTask, errorTask); + context.Log.Information($"Process exited with code: {process.ExitCode}"); + } + + return retVal; + } + } } \ No newline at end of file diff --git a/cake/Program.cs b/cake/Program.cs index 0e00dc628..a069a94cd 100644 --- a/cake/Program.cs +++ b/cake/Program.cs @@ -399,142 +399,21 @@ public override void Run(BuildContext context) context.DotNetTest(Path.Combine(context.RootDir, package.folder, "tmp_L3_.proj"), context.DotNetTestSettings); } } - - context.Log.Information("Tests done."); - } -} - -[TaskName("AppsRun")] -[IsDependentOn(typeof(TestsTask))] -public sealed class AppsRunTask : FrostingTask -{ - // Tasks can be asynchronous - public override void Run(BuildContext context) - { - if (!context.BuildParameters.AppsRun) + if (context.BuildParameters.TestLevel >= 4) { - context.Log.Warning($"Skipping apps run"); - return; + // Full end-to-end smoke test of the consolidated showcase app: load the entire PLC + // (incl. hardware configuration) onto PLCSIM Advanced, then run the Blazor server and + // assert it serves traffic. Fails the build on any error. + var showcaseApp = Path.Combine(context.RootDir, "showcase", "app", "apax.yml"); + AppsRunTaskHelpers.RunShowcaseIntegration(context, showcaseApp); } - AppsRunTaskHelpers.KillProcess(context,"Siemens.Simatic.PlcSim.Advanced.UserInterface"); - - bool summaryResult = true; - - if (string.IsNullOrEmpty(context.BuildParameters.AppRunOnlyFolderName)) - { - var createResult = AppsRunTaskHelpers.CreateLogFile(context, "app_test_result"); - - if (createResult.Success) - { - string logFilePath = createResult.FilePath; - AppsRunTaskHelpers.WriteResult(context, "AppName,PlcSim,PlcHw,PlcSw,DotnetBuild,DotnetRun", logFilePath); - - foreach (var library in context.Libraries) - { - if (library.app_run) - { - string appFolder = context.GetAppFolder(library); - string appFile = context.GetApaxFile(appFolder); - string appName = context.GetApplicationName(appFile); - - if (!string.IsNullOrEmpty(appFolder) && context.DirectoryExists(appFolder) && !string.IsNullOrEmpty(appFile) && context.FileExists(appFile) && !string.IsNullOrEmpty(appName)) - { - // Display the file details - context.Log.Information($"###################################################"); - context.Log.Information($"Starting the application: {appName}"); - context.Log.Information($"File of the application: {appFile}"); - context.Log.Information($"###################################################"); - AppsRunTaskHelpers.WriteResult(context, " ", logFilePath); - AppsRunTaskHelpers.WriteResult(context, appName, logFilePath, appendToSameLine: true); - - // Cleanup JSONREPOS - AppsRunTaskHelpers.DeleteJsonReposFolder(context, appFolder); - - // Initialize PLC Sim instance - AppsRunTaskHelpers.InitializePlcSimInstance(context, appName); - - // Overwrite security files - AppsRunTaskHelpers.OverwriteSecurityFiles(context, appFile, context.PlcName); - - // Build and load PLC - AppsRunTaskHelpers.BuildAndLoadPlc(context, appFile, appName, logFilePath, ref summaryResult); - - // Build and start HMI - AppsRunTaskHelpers.BuildAndStartHmi(context, appFile, appName, logFilePath, ref summaryResult); - - - } - } - } - - if (!summaryResult) - { - context.Log.Error($"App run failed for some of the applications."); - context.Log.Error($"Good luck with finding out the reason :-)."); - Environment.Exit(1); - } - } - else - { - Console.Error.WriteLine("Failed to create the log file."); - } - } - else - { - var createResult = AppsRunTaskHelpers.CreateLogFile(context, "single_app_test_result"); - - if (createResult.Success) - { - string logFilePath = createResult.FilePath; - AppsRunTaskHelpers.WriteResult(context, "AppName,ApaxInstall,ApaxPlcSim,ApaxGsd,ApaxHwl,ApaxHwcc,ApaxHwid,ApaxHwadr,ApaxHwdo,ApaxBuild,DotnetIxc,ApaxSlfdo,Slngen,DotnetClean,DotnetBuild,DotnetRun", logFilePath); - - string appFolder = Path.Combine(context.RootDir, context.BuildParameters.AppRunOnlyFolderName); - string appFile = context.GetApaxFile(appFolder); - string appName = context.GetApplicationName(appFile); - - if (!string.IsNullOrEmpty(appFolder) && context.DirectoryExists(appFolder) && !string.IsNullOrEmpty(appFile) && context.FileExists(appFile) && !string.IsNullOrEmpty(appName)) - { - // Display the file details - context.Log.Information($"###################################################"); - context.Log.Information($"Starting the application: {appName}"); - context.Log.Information($"File of the application: {appFile}"); - context.Log.Information($"###################################################"); - AppsRunTaskHelpers.WriteResult(context, " ", logFilePath); - AppsRunTaskHelpers.WriteResult(context, appName, logFilePath, appendToSameLine: true); - - // Cleanup JSONREPOS - AppsRunTaskHelpers.DeleteJsonReposFolder(context, appFolder); - - // Initialize PLC Sim instance - AppsRunTaskHelpers.InitializePlcSimInstance(context, appName); - - // Overwrite security files - AppsRunTaskHelpers.OverwriteSecurityFiles(context, appFile, context.PlcName); - - // Build and load PLC, build and start HMI with more grannular evaluation - AppsRunTaskHelpers.AppRunDetailed(context, appFile, appName, logFilePath, ref summaryResult); - - if (!summaryResult) - { - context.Log.Error($"App run failed for the application name: '{appName}', application file: '{appFile}' in folder: '{appFolder}'"); - Environment.Exit(1); - } - } - } - else - { - Console.Error.WriteLine("Failed to create the log file."); - } - } - - AppsRunTaskHelpers.KillProcess(context, "Siemens.Simatic.PlcSim.Advanced.UserInterface"); - context.Log.Information("Apps run done."); + context.Log.Information("Tests done."); } } [TaskName("CreateArtifacts")] -[IsDependentOn(typeof(AppsRunTask))] +[IsDependentOn(typeof(TestsTask))] public sealed class CreateArtifactsTask : FrostingTask { public override void Run(BuildContext context) diff --git a/cake/Properties/launchSettings.json b/cake/Properties/launchSettings.json index 53666dfa1..131b89751 100644 --- a/cake/Properties/launchSettings.json +++ b/cake/Properties/launchSettings.json @@ -20,6 +20,10 @@ "commandName": "Project", "commandLineArgs": "--do-test --test-level 10" }, + "test-L4": { + "commandName": "Project", + "commandLineArgs": "--do-test --test-level 4" + }, "no-build": { "commandName": "Project", "commandLineArgs": "--skip-build" @@ -31,122 +35,6 @@ "build": { "commandName": "Project", "commandLineArgs": "" - }, - "test-L3-apps_run": { - "commandName": "Project", - "commandLineArgs": "--do-test --test-level 10 --apps-run" - }, - "apps_run_only": { - "commandName": "Project", - "commandLineArgs": "--skip-build --apps-run" - }, - "abstractions_app_run_only": { - "commandName": "Project", - "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name abstractions" - }, - "components.abb.robotics_app_run_only": { - "commandName": "Project", - "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name components.abb.robotics" - }, - "components.abstractions_app_run_only": { - "commandName": "Project", - "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name components.abstractions" - }, - "components.balluff.identification_app_run_only": { - "commandName": "Project", - "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name components.balluff.identification" - }, - "components.cognex.vision_app_run_only": { - "commandName": "Project", - "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name components.cognex.vision" - }, - "components.desoutter.tightening_app_run_only": { - "commandName": "Project", - "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name components.desoutter.tightening" - }, - "components.drives_app_run_only": { - "commandName": "Project", - "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name components.drives" - }, - "components.elements_app_run_only": { - "commandName": "Project", - "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name components.elements" - }, - "components.festo.drives_app_run_only": { - "commandName": "Project", - "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name components.festo.drives" - }, - "components.kuka.robotics_app_run_only": { - "commandName": "Project", - "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name components.kuka.robotics" - }, - "components.keyence.vision_app_run_only": { - "commandName": "Project", - "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name components.keyence.vision" - }, - "components.mitsubishi.robotics_app_run_only": { - "commandName": "Project", - "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name components.mitsubishi.robotics" - }, - "components.pneumatics_app_run_only": { - "commandName": "Project", - "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name components.pneumatics" - }, - "components.rexroth.drives_app_run_only": { - "commandName": "Project", - "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name components.rexroth.drives" - }, - "components.rexroth.press_app_run_only": { - "commandName": "Project", - "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name components.rexroth.press" - }, - "components.robotics_app_run_only": { - "commandName": "Project", - "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name components.robotics" - }, - "components.siem.identification_app_run_only": { - "commandName": "Project", - "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name components.siem.identification" - }, - "components.ur.robotics_app_run_only": { - "commandName": "Project", - "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name components.ur.robotics" - }, - "core_app_run_only": { - "commandName": "Project", - "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name core" - }, - "data_app_run_only": { - "commandName": "Project", - "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name data" - }, - "inspectors_app_run_only": { - "commandName": "Project", - "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name inspectors" - }, - "io_app_run_only": { - "commandName": "Project", - "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name io" - }, - "probers_app_run_only": { - "commandName": "Project", - "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name probers" - }, - "simatic1500_app_run_only": { - "commandName": "Project", - "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name simatic1500" - }, - "template.axolibrary_app_run_only": { - "commandName": "Project", - "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name template.axolibrary" - }, - "timers_app_run_only": { - "commandName": "Project", - "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name timers" - }, - "utils_app_run_only": { - "commandName": "Project", - "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name utils" } } -} \ No newline at end of file +} diff --git a/scripts/_deps-common.ps1 b/scripts/_deps-common.ps1 new file mode 100644 index 000000000..6db927c92 --- /dev/null +++ b/scripts/_deps-common.ps1 @@ -0,0 +1,153 @@ +#!/usr/bin/env pwsh +<# +.SYNOPSIS +Shared helpers for dependency-management scripts (dot-source this file). + +.DESCRIPTION +Common logging, file IO, semver comparison, NuGet v3 feed access, token discovery and +severity utilities used by scripts/update-vulnerable-deps.ps1 (and reusable by +scripts/update_axsharp_versions.ps1). Several functions here originated in +update_axsharp_versions.ps1 and were factored out so the two scripts share one source of truth. + +Dot-source it from a script: + . "$PSScriptRoot/_deps-common.ps1" +#> + +# --------------------------------------------------------------------------- +# Logging +# --------------------------------------------------------------------------- +function Write-Info($msg){ Write-Host "[INFO ] $msg" -ForegroundColor Cyan } +function Write-Warn($msg){ Write-Host "[WARN ] $msg" -ForegroundColor Yellow } +function Write-Err ($msg){ Write-Host "[ERROR] $msg" -ForegroundColor Red } + +# --------------------------------------------------------------------------- +# File IO +# --------------------------------------------------------------------------- +function Write-Utf8NoBom-LF { + # Writes text as UTF-8 (no BOM) with LF line endings to preserve repo conventions. + param([string]$Path, [string]$Content) + $lf = ($Content -replace "`r`n", "`n") -replace "`r", "`n" + [System.IO.File]::WriteAllText($Path, $lf, [System.Text.UTF8Encoding]::new($false)) +} + +# --------------------------------------------------------------------------- +# Token discovery +# --------------------------------------------------------------------------- +function Resolve-FeedToken { + # Returns the first non-empty token from the supplied value or the candidate env vars. + param( + [string]$Token, + [string[]]$EnvCandidates = @('NUGET_TOKEN','GITHUB_PACKAGES_TOKEN','GITHUB_TOKEN','GH_TOKEN'), + [switch]$Detailed + ) + if($Token){ return $Token } + foreach($c in $EnvCandidates){ + $candidate = [Environment]::GetEnvironmentVariable($c) + if($candidate){ + if($Detailed){ Write-Info "Using token from environment variable $c" } + return $candidate + } + } + return $null +} + +# --------------------------------------------------------------------------- +# Semver parsing / comparison (build metadata ignored for ordering) +# --------------------------------------------------------------------------- +function ConvertTo-VersionRecord { + param([string]$v) + $core = $v + $pre = '' + $buildSplit = $core.Split('+',2) + if($buildSplit.Count -gt 1){ $core = $buildSplit[0] } + $dashIdx = $core.IndexOf('-') + if($dashIdx -ge 0){ + $pre = $core.Substring($dashIdx + 1) + $core = $core.Substring(0,$dashIdx) + } + $parts = $core.Split('.') + [int]$maj = if($parts.Count -gt 0){ $parts[0] } else { 0 } + [int]$min = if($parts.Count -gt 1){ $parts[1] } else { 0 } + [int]$pat = if($parts.Count -gt 2){ $parts[2] } else { 0 } + $preSegs = @() + if($pre){ $preSegs = $pre.Split('.') } + [PSCustomObject]@{ Original=$v; Major=$maj; Minor=$min; Patch=$pat; Pre=$pre; PreSegs=$preSegs } +} + +function Compare-VersionRecord { + param($a,$b) + if($a.Major -ne $b.Major){ return [Math]::Sign($a.Major - $b.Major) } + if($a.Minor -ne $b.Minor){ return [Math]::Sign($a.Minor - $b.Minor) } + if($a.Patch -ne $b.Patch){ return [Math]::Sign($a.Patch - $b.Patch) } + $aHasPre = [string]::IsNullOrEmpty($a.Pre) -ne $true + $bHasPre = [string]::IsNullOrEmpty($b.Pre) -ne $true + if($aHasPre -and -not $bHasPre){ return -1 } + if($bHasPre -and -not $aHasPre){ return 1 } + if(-not $aHasPre -and -not $bHasPre){ return 0 } + $len = [Math]::Max($a.PreSegs.Count,$b.PreSegs.Count) + for($i=0;$i -lt $len;$i++){ + if($i -ge $a.PreSegs.Count){ return -1 } + if($i -ge $b.PreSegs.Count){ return 1 } + $as = $a.PreSegs[$i]; $bs = $b.PreSegs[$i] + $aNum = $as -as [int]; $bNum = $bs -as [int] + $aIsNum = $aNum -ne $null; $bIsNum = $bNum -ne $null + if($aIsNum -and $bIsNum){ if($aNum -ne $bNum){ return [Math]::Sign($aNum - $bNum) } } + elseif($aIsNum -and -not $bIsNum){ return -1 } + elseif($bIsNum -and -not $aIsNum){ return 1 } + else { $cmp = [string]::Compare($as,$bs,$true); if($cmp -ne 0){ return [Math]::Sign($cmp) } } + } + return 0 +} + +function Test-VersionGreater { + # Returns $true when semver-ish version $A is strictly greater than $B. + param([string]$A,[string]$B) + if([string]::IsNullOrWhiteSpace($B)){ return $true } + if([string]::IsNullOrWhiteSpace($A)){ return $false } + return ( (Compare-VersionRecord (ConvertTo-VersionRecord $A) (ConvertTo-VersionRecord $B)) -gt 0 ) +} + +function Test-IsPrerelease { + param([string]$v) + if([string]::IsNullOrWhiteSpace($v)){ return $false } + return -not [string]::IsNullOrEmpty((ConvertTo-VersionRecord $v).Pre) +} + +# --------------------------------------------------------------------------- +# NuGet v3 feed access +# --------------------------------------------------------------------------- +function Get-FeedContext { + # Resolves the service index once and returns the PackageBaseAddress + auth headers + # for reuse across multiple package requests. + param([string]$Feed,[string]$User,[string]$Tok) + $serviceIndexUrl = if($Feed.ToLower().EndsWith('index.json')) { $Feed } else { ($Feed.TrimEnd('/')) + '/index.json' } + $headers = @{} + if($Tok){ + $u = if($User){$User}else{'USERNAME'} + $basic = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $u,$Tok))) + $headers['Authorization'] = "Basic $basic" + } + $si = Invoke-RestMethod -Uri $serviceIndexUrl -Headers $headers -TimeoutSec 30 + if(-not $si.resources){ throw "Service index missing resources at $serviceIndexUrl" } + $pkgBase = ($si.resources | Where-Object { $_.'@type' -eq 'PackageBaseAddress/3.0.0' } | Select-Object -First 1).'@id' + if(-not $pkgBase){ throw 'PackageBaseAddress/3.0.0 resource not found in service index.' } + if($pkgBase[-1] -ne '/') { $pkgBase += '/' } + [PSCustomObject]@{ PkgBase=$pkgBase; Headers=$headers } +} + +function Get-PackageVersionsFromFeed { + # Returns the raw list of available version strings for a package id on a v3 feed. + param([string]$PkgBase,[hashtable]$Headers,[string]$PackageId) + $lowerId = $PackageId.ToLower() + $indexUrl = "$PkgBase$lowerId/index.json" + try { + $idx = Invoke-RestMethod -Uri $indexUrl -Headers $Headers -TimeoutSec 30 + } catch { + $code = $null + if($_.Exception.Response){ $code = [int]$_.Exception.Response.StatusCode } + if($code -eq 404){ return @() } # package id unknown on this feed + throw "Failed to fetch version index ($indexUrl): $($_.Exception.Message)" + } + if(-not $idx.versions){ return @() } + return $idx.versions +} diff --git a/scripts/test_L4.ps1 b/scripts/test_L4.ps1 new file mode 100644 index 000000000..f76ea7585 --- /dev/null +++ b/scripts/test_L4.ps1 @@ -0,0 +1,4 @@ +# run build + +dotnet run --project cake/Build.csproj --do-test --test-level 4 -n +exit $LASTEXITCODE; \ No newline at end of file diff --git a/scripts/update-ax-catalog.ps1 b/scripts/update-ax-catalog.ps1 new file mode 100644 index 000000000..a920c2fd2 --- /dev/null +++ b/scripts/update-ax-catalog.ps1 @@ -0,0 +1,731 @@ +#!/usr/bin/env pwsh +<# +.SYNOPSIS +Updates the @ax/* dependencies of the local apax catalog (@inxton/ax.catalog) to the latest versions, +bumps the catalog version, syncs every catalog consumer, and publishes the catalog (Phase 1); then +verifies the build (Phase 2, -AfterPublish). + +.DESCRIPTION +The repo pins all Simatic AX (@ax/*) package versions centrally in the apax catalog at +src/ax.catalog/apax.yml (package @inxton/ax.catalog). The catalog CONSUMERS are the per-library +manifests src//ctrl/apax.yml that declare a `catalogs:` block referencing @inxton/ax.catalog and +re-pin a subset of @ax/* packages in their own `dependencies:`. Consumers are discovered dynamically. + +NOTE on ctrl/ and build noise: the consumer manifest lives at src//ctrl/apax.yml (git-tracked) and +is the file apax install reads, so this script edits it directly. During `apax pack`, cake stamps the +GitVersion SemVer into each manifest's `version` and @inxton/* deps (it leaves @ax/* and the .catalog +reference alone - see cake BuildContext.UpdateApaxVersion/UpdateApaxDependencies). Those stamps are +unwanted build noise, so Phase 2 commits our edits, runs the build, then restores every build-touched +tracked file back to that commit and un-commits - leaving ONLY our @ax/catalog edits staged. + +Editing files needs no published catalog - only the cake VERIFY build (which runs apax install) does. +So all editing + publishing happens in Phase 1, and verification is the separate Phase 2 (because a +published catalog version cannot be cleanly un-published, the build verification is deliberately AFTER +the publish - run it and inspect before relying on the new catalog): + + PHASE 1 (default) - refresh catalog + sync consumers + publish: + 1. Capture the current @ax/* versions. + 2. Resolve each @ax/* dep's highest non-deprecated version from the AX registry via + `apax list -p ` (stable; -Prerelease widens to prereleases) and rewrite the catalog's + catalogDependencies. (`apax update` is NOT used - it ignores a catalog's catalogDependencies.) + 3. If (and only if) at least one @ax/* dep changed: auto-bump the catalog `version` (patch, or + -CatalogVersion), and sync every discovered consumer (src//ctrl/apax.yml) - their explicit + @ax/* pins to the new catalog versions and their `catalogs: "@inxton/ax.catalog"` reference. + 4. Write a report under scripts/reports/. + 5. Publish the catalog by invoking scripts/_pack_and_publish_catalog.ps1 (unless -NoPublish, or a + -DryRun, or nothing changed). Then STOP - run -AfterPublish to verify. + + PHASE 2 (-AfterPublish) - verify: + 1. Re-assert consumer sync as an idempotent guard (normally a no-op). + 2. Pre-build commit ONLY our edited manifests (catalog + consumers). + 3. Verify with cake TESTS at level 2: `dotnet run --project cake/Build.csproj --do-test + --test-level 2 -n` (cake runs apax install --catalog --strict + build per consumer, then the L2 + .NET test suite). Not pack - so cake does not stamp SemVer into the manifests. + 4. Discard build-produced changes WITHOUT touching your other uncommitted work: restore build-changed + tracked files (excluding files that were already dirty before this run) back to the commit, then + `git reset --soft HEAD~1` so our edits remain STAGED. No `git clean` (protects untracked files). + +Phase 1 publishes automatically when there are changes; pass -NoPublish to keep the old manual gate. + +.PARAMETER AfterPublish +Run Phase 2 (cake verify, with an idempotent consumer-sync guard). Use after Phase 1 has published. + +.PARAMETER Prerelease +Include prerelease versions when resolving "latest" (otherwise the highest non-deprecated stable version +is used). Default: stable only. + +.PARAMETER CatalogVersion +Explicit new catalog version (overrides the automatic patch bump). Phase 1 only. + +.PARAMETER NoPublish +Phase 1 only: update + sync but do NOT auto-publish; print the manual publish/verify steps instead. + +.PARAMETER DryRun +Preview everything; write no files, make no git changes, publish nothing, run no cake build. + +.PARAMETER Detailed +Verbose logging. + +.EXAMPLE +./update-ax-catalog.ps1 -DryRun -Detailed # Phase 1 preview: @ax old->new, version, consumer edits + +.EXAMPLE +./update-ax-catalog.ps1 # Phase 1: refresh + bump + sync + auto-publish + +.EXAMPLE +./update-ax-catalog.ps1 -NoPublish # Phase 1: refresh + bump + sync, but DON'T publish + +.EXAMPLE +./update-ax-catalog.ps1 -AfterPublish # Phase 2: cake-verify, discard build noise +#> + +[CmdletBinding()] +param( + [switch]$AfterPublish, + [switch]$Prerelease, + [string]$CatalogVersion, + [switch]$NoPublish, + [switch]$DryRun, + [switch]$Detailed +) + +Set-StrictMode -Version Latest +$ErrorActionPreference = 'Stop' + +$scriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path +. "$scriptRoot/_deps-common.ps1" + +$repoRoot = Split-Path -Parent $scriptRoot +$catalogDir = Join-Path $repoRoot 'src/ax.catalog' +$catalogYml = Join-Path $catalogDir 'apax.yml' +$cakeProj = Join-Path $repoRoot 'cake/Build.csproj' +$catalogPkg = '@inxton/ax.catalog' +$publishScript = Join-Path $scriptRoot '_pack_and_publish_catalog.ps1' + +# Catalog consumers are DISCOVERED dynamically (see Get-CatalogConsumers): any apax.yml whose +# `catalogs:` block references @inxton/ax.catalog. This is the same marker cake's ApaxCatalogInstall +# keys on, so new libraries that adopt the catalog are picked up automatically. + +# --------------------------------------------------------------------------- +# Small helpers +# --------------------------------------------------------------------------- +function Test-CommandAvailable { param([string]$Name) $null -ne (Get-Command $Name -ErrorAction SilentlyContinue) } + +# Repo-root-relative, forward-slash path (matches `git status --porcelain` output). +function ConvertTo-RepoRelative { + param([string]$Path) + $full = [System.IO.Path]::GetFullPath($Path) + $root = [System.IO.Path]::GetFullPath($repoRoot) + if($full.StartsWith($root, [StringComparison]::OrdinalIgnoreCase)){ + $full = $full.Substring($root.Length).TrimStart('\','/') + } + return ($full -replace '\\','/') +} + +# Dependency-line regexes. Tolerant of single/double quoting, any indentation, and an optional +# trailing comment (the catalog pins carry `# ...` provenance notes). Group layout for the dep +# regexes: 1=indent+openquote 2=key 3=closequote+colon+space 4=value-openquote 5=version +# 6=value-closequote 7=trailing (whitespace + optional #comment), preserved on rewrite. +$AxDepRx = '^(\s+[''"]?)(@ax/[^''":\s]+)([''"]?\s*:\s*)([''"]?)([^''"\s#]+)([''"]?)(\s*(?:#.*)?)$' +$CatalogRefRx = '^(\s+[''"]?)(@inxton/ax\.catalog)([''"]?\s*:\s*)([''"]?)([^''"\s#]+)([''"]?)(\s*(?:#.*)?)$' +$VersionRx = '^(version\s*:\s*)([''"]?)([^''"\s#]+)([''"]?)(\s*(?:#.*)?)$' + +# Parse a top-level section of `key: value` deps and return @ax/* entries as an ordered map. +function Get-AxDepsInSection { + param([string[]]$Lines, [string]$Section) + $map = [ordered]@{} + $cur = $null + foreach($ln in $Lines){ + if($ln -match '^[A-Za-z]'){ # zero-indent => a top-level key + if($ln -match '^([A-Za-z][\w\.]*)\s*:'){ $cur = $Matches[1] } + continue + } + if($cur -ne $Section){ continue } + if($ln -match $AxDepRx){ $map[$Matches[2]] = $Matches[5] } + } + return $map +} + +# True when these apax.yml lines declare a `catalogs:` block that references the catalog package. +function Test-IsCatalogConsumer { + param([string[]]$Lines) + $cur = $null + foreach($ln in $Lines){ + if($ln -match '^[A-Za-z]'){ + if($ln -match '^([A-Za-z][\w\.]*)\s*:'){ $cur = $Matches[1] } + continue + } + if($cur -eq 'catalogs' -and $ln -match $CatalogRefRx){ return $true } + } + return $false +} + +# Discover every catalog consumer under src/: an apax.yml whose `catalogs:` block references +# @inxton/ax.catalog. In this repo the per-library manifest lives at src//ctrl/apax.yml (tracked +# in git) - that IS the file we edit and that apax install reads. We exclude only the dependency-copy +# / build-output dirs (.apax cache, bin, obj, node_modules), NOT ctrl. Sorted, absolute. +function Get-CatalogConsumers { + $srcRoot = Join-Path $repoRoot 'src' + if(-not (Test-Path -LiteralPath $srcRoot)){ return @() } + $excludeRx = '[\\/](bin|obj|\.apax|node_modules|wwwroot|dist|\.git|\.vs)[\\/]' + $catalogFull = [System.IO.Path]::GetFullPath($catalogYml) + Get-ChildItem -LiteralPath $srcRoot -Recurse -File -Filter 'apax.yml' -ErrorAction SilentlyContinue | + Where-Object { $_.FullName -notmatch $excludeRx } | + Where-Object { [System.IO.Path]::GetFullPath($_.FullName) -ne $catalogFull } | + Where-Object { Test-IsCatalogConsumer -Lines (Get-Content -LiteralPath $_.FullName) } | + Select-Object -ExpandProperty FullName | + Sort-Object +} + +# Read the top-level `version:` value from catalog content. +function Get-CatalogVersion { + param([string[]]$Lines) + foreach($ln in $Lines){ if($ln -match $VersionRx){ return $Matches[3] } } + return $null +} + +# Patch-bump a semver string (x.y.z -> x.y.(z+1)). +function Get-NextPatchVersion { + param([string]$Version) + $rec = ConvertTo-VersionRecord $Version + return ('{0}.{1}.{2}' -f $rec.Major, $rec.Minor, ($rec.Patch + 1)) +} + +# Strip ANSI/VT escape sequences from apax's coloured output so it can be parsed. +function Remove-Ansi { param([string]$Text) return ([regex]::Replace($Text, "\x1B\[[0-9;]*[A-Za-z]", '')) } + +# Query the AX registry for one package via `apax list -p ` and return its latest dist-tag plus the +# full version list (each flagged deprecated/prerelease). apax has no JSON mode and writes to stderr, so +# we merge streams, strip ANSI, and parse the "Versions" / "Tags(latest:)" sections. $LASTEXITCODE is +# unreliable here (apax emits info banners on stderr), so success is judged by whether we parsed a tag +# or any versions. Returns $null when the package can't be read. +function Get-AxPackageInfo { + param([string]$Package, [int]$Retries = 2) + # apax list can occasionally return an empty/partial response (registry warmup). Retry a couple of + # times until we get output that contains a Versions/Tags section before giving up. + $prevEap = $ErrorActionPreference + $ErrorActionPreference = 'Continue' + $clean = '' + try { + for($attempt = 0; $attempt -le $Retries; $attempt++){ + $raw = '' + try { $raw = (& apax list -p $Package 2>&1 | Out-String) } catch { $raw = '' } + $clean = Remove-Ansi $raw + if($clean -match '(?m)^\s*(Versions|Tags)\s*$'){ break } + } + } finally { $ErrorActionPreference = $prevEap } + $latest = $null + $versions = New-Object System.Collections.ArrayList + $inVersions = $false; $inTags = $false + foreach($ln in ($clean -split "`r?`n")){ + $t = $ln.Trim() + if($t -eq 'Versions'){ $inVersions = $true; $inTags = $false; continue } + if($t -eq 'Tags'){ $inTags = $true; $inVersions = $false; continue } + # A non-list, non-section header line ends the current section. + if($t -match '^[A-Za-z]' -and $t -notmatch '^-\s'){ $inVersions = $false; $inTags = $false } + if($inVersions -and $t -match '^-\s*([0-9][^\s]*)'){ + $v = $Matches[1] + [void]$versions.Add([PSCustomObject]@{ Version=$v; Deprecated=($t -match 'deprecated'); Prerelease=(Test-IsPrerelease $v) }) + } + if($inTags -and $t -match 'latest:\s*([^\s]+)'){ $latest = $Matches[1] } + } + if(-not $latest -and $versions.Count -eq 0){ return $null } + return [PSCustomObject]@{ Package=$Package; Latest=$latest; Versions=@($versions) } +} + +# Pick the version to move a package to: the HIGHEST non-deprecated published version. We deliberately +# do NOT use the registry 'latest' dist-tag, because on the AX registry it can point below the highest +# published version (e.g. @ax/ax2tia latest=11.1.25 while 12.2.8 is published) - taking it would +# downgrade a pin. Stable mode excludes prereleases; -Prerelease includes them. Returns $null if none. +function Select-TargetVersion { + param($Info) + if(-not $Info){ return $null } + # Wrap the whole if-expression in @() - assigning a one-element array via `if` would unwrap it to a + # scalar, breaking the .Count check under StrictMode. + $cand = @(if($Prerelease){ $Info.Versions | Where-Object { -not $_.Deprecated } } + else { $Info.Versions | Where-Object { -not $_.Deprecated -and -not $_.Prerelease } }) + if($cand.Count -eq 0){ return $null } + $best = $cand[0].Version + foreach($c in $cand){ if(Test-VersionGreater $c.Version $best){ $best = $c.Version } } + return $best +} + +# True when moving From -> To crosses a major-version boundary (used to flag, not block). +function Test-IsMajorBump { + param([string]$From,[string]$To) + if([string]::IsNullOrWhiteSpace($From) -or [string]::IsNullOrWhiteSpace($To)){ return $false } + return ((ConvertTo-VersionRecord $To).Major -gt (ConvertTo-VersionRecord $From).Major) +} + +# Resolve the latest target version for every @ax/* key in $OldMap by querying the registry. Returns an +# ordered map (same key order as $OldMap). NEVER downgrades: if the resolved highest version is not +# strictly greater than the current pin, the current pin is kept (covers a lagging 'latest', a yanked +# higher version, or an already-current pin). Unresolvable keys keep their current version with a +# warning. Pure read - touches no file. +function Resolve-LatestAxVersions { + param($OldMap) + $newMap = [ordered]@{} + $i = 0; $total = $OldMap.Count + $updated = 0; $kept = 0; $failed = 0 + foreach($pkg in $OldMap.Keys){ + $i++ + $cur = $OldMap[$pkg] + # Live progress: a progress bar plus a single rewriting status line, so 77 sequential registry + # queries don't look frozen. (Write-Progress is suppressed in non-interactive hosts; the inline + # counter still shows. -Detailed additionally logs the per-package outcome below.) + $pct = [int](($i-1) * 100 / [Math]::Max($total,1)) + Write-Progress -Activity 'Resolving @ax/* latest versions' -Status ("[{0}/{1}] {2}" -f $i,$total,$pkg) -PercentComplete $pct + Write-Host ("`r [{0,2}/{1}] querying {2,-45}" -f $i,$total,$pkg) -NoNewline -ForegroundColor DarkGray + + $info = Get-AxPackageInfo -Package $pkg + $target = Select-TargetVersion -Info $info + if(-not $target){ + $failed++; $newMap[$pkg] = $cur + Write-Host "`r" -NoNewline + Write-Warn (" [{0}/{1}] {2}: could not resolve latest - keeping {3}" -f $i,$total,$pkg,$cur) + continue + } + if(Test-VersionGreater $target $cur){ + $updated++; $newMap[$pkg] = $target + if($Detailed){ Write-Host "`r" -NoNewline; Write-Info (" [{0}/{1}] {2}: {3} -> {4}" -f $i,$total,$pkg,$cur,$target) } + } else { + # Resolved version is <= current pin: keep current (no downgrade). Note when the registry's + # highest is actually lower than what we have pinned. + $kept++; $newMap[$pkg] = $cur + if($Detailed){ + Write-Host "`r" -NoNewline + if(Test-VersionGreater $cur $target){ Write-Info (" [{0}/{1}] {2}: {3} (registry highest {4} is lower - kept)" -f $i,$total,$pkg,$cur,$target) } + else { Write-Info (" [{0}/{1}] {2}: {3} (already latest)" -f $i,$total,$pkg,$cur) } + } + } + } + Write-Host ("`r{0,-72}" -f '') -NoNewline; Write-Host "`r" -NoNewline # clear the status line + Write-Progress -Activity 'Resolving @ax/* latest versions' -Completed + Write-Info ("Resolved {0} package(s): {1} to update, {2} already current, {3} unresolved." -f $total,$updated,$kept,$failed) + return $newMap +} + +# Rewrite the catalogDependencies section of the catalog file in place from $NewMap, preserving line +# formatting and trailing comments. Only @ax/* lines whose version changed are touched. +function Update-CatalogDepsFile { + param([string]$Path, $NewMap) + $lines = Get-Content -LiteralPath $Path + $cur = $null + $out = foreach($ln in $lines){ + if($ln -match '^[A-Za-z]'){ + if($ln -match '^([A-Za-z][\w\.]*)\s*:'){ $cur = $Matches[1] } + $ln; continue + } + if($cur -eq 'catalogDependencies' -and $ln -match $AxDepRx){ + $pkg = $Matches[2]; $oldv = $Matches[5] + if($NewMap.Contains($pkg) -and $NewMap[$pkg] -ne $oldv){ + "$($Matches[1])$pkg$($Matches[3])$($Matches[4])$($NewMap[$pkg])$($Matches[6])$($Matches[7])".TrimEnd(); continue + } + $ln; continue + } + $ln + } + Write-Utf8NoBom-LF -Path $Path -Content (($out -join "`n") + "`n") +} + +# Pack + publish the catalog to the @inxton registry by invoking the existing pack/publish script. +# Returns $true on success. Requires APAX_KEY (and GH_USER/GH_TOKEN if the registry login isn't cached). +function Invoke-CatalogPublish { + if(-not (Test-Path -LiteralPath $publishScript)){ Write-Err "Publish script not found: $publishScript"; return $false } + if(-not $env:APAX_KEY){ Write-Err 'APAX_KEY is not set - cannot pack/publish the catalog. Set APAX_KEY (and GH_USER/GH_TOKEN) and re-run, or pass -NoPublish.'; return $false } + Write-Info "Publishing catalog: $publishScript" + $prevEap = $ErrorActionPreference + $ErrorActionPreference = 'Continue' + try { & $publishScript } finally { $ErrorActionPreference = $prevEap } + if($LASTEXITCODE -and $LASTEXITCODE -ne 0){ Write-Err "Publish script exited with code $LASTEXITCODE."; return $false } + return $true +} + +# --------------------------------------------------------------------------- +# Report +# --------------------------------------------------------------------------- +function Write-Report { + param([string]$Stamp, [string]$Phase, $Payload, [string]$MarkdownBody) + $reportsDir = Join-Path $scriptRoot 'reports' + if(-not (Test-Path $reportsDir)){ New-Item -ItemType Directory -Path $reportsDir -Force | Out-Null } + $base = "ax-catalog-$Phase-$Stamp" + $mdPath = Join-Path $reportsDir "$base.md" + $jsonPath = Join-Path $reportsDir "$base.json" + Write-Utf8NoBom-LF -Path $jsonPath -Content ($Payload | ConvertTo-Json -Depth 8) + Write-Utf8NoBom-LF -Path $mdPath -Content $MarkdownBody + Write-Info "Report: $mdPath" + return $mdPath +} + +function Format-DiffTable { + # Builds a markdown table of @ax old->new from two ordered maps. + param($OldMap, $NewMap) + $sb = New-Object System.Text.StringBuilder + [void]$sb.AppendLine('| Package | From | To |') + [void]$sb.AppendLine('|---|---|---|') + $keys = @($OldMap.Keys) + @($NewMap.Keys) | Select-Object -Unique | Sort-Object + foreach($k in $keys){ + $from = if($OldMap.Contains($k)){ $OldMap[$k] } else { '(new)' } + $to = if($NewMap.Contains($k)){ $NewMap[$k] } else { '(removed)' } + if($from -ne $to){ [void]$sb.AppendLine("| $k | $from | $to |") } + } + return $sb.ToString() +} + +# =========================================================================== +# PHASE 1 - refresh catalog +# =========================================================================== +function Invoke-Phase1 { + param([string]$Stamp) + Write-Info '== PHASE 1: refresh @inxton/ax.catalog ==' + if(-not (Test-CommandAvailable 'apax')){ Write-Err 'apax CLI not found on PATH.'; exit 2 } + if(-not (Test-Path -LiteralPath $catalogYml)){ Write-Err "Catalog not found: $catalogYml"; exit 2 } + + $origLines = Get-Content -LiteralPath $catalogYml + $oldMap = Get-AxDepsInSection -Lines $origLines -Section 'catalogDependencies' + $oldVersion = Get-CatalogVersion -Lines $origLines + if(-not $oldVersion){ Write-Err 'Could not read catalog version field.'; exit 2 } + Write-Info "Catalog at $oldVersion ($($oldMap.Count) @ax/* deps). Resolving latest versions..." + + # Resolve the latest version of every @ax/* dep by querying the AX registry directly with + # `apax list -p `. NOTE: `apax update` only touches dependencies/devDependencies "from the + # apax.yml" - it does NOT update a catalog's catalogDependencies (verified: it reports "No updates + # available" on this catalog), which is why we resolve each pin ourselves. This is a pure read; the + # file is rewritten below only when something actually changed. + $newMap = Resolve-LatestAxVersions -OldMap $oldMap + + # Diff summary (version-changed @ax/* deps; the set of keys is fixed by the catalog). Major bumps are + # flagged for review but still applied. + $changed = @() + foreach($k in $newMap.Keys){ + if($oldMap[$k] -ne $newMap[$k]){ $changed += [PSCustomObject]@{ Package=$k; From=$oldMap[$k]; To=$newMap[$k]; IsMajor=(Test-IsMajorBump $oldMap[$k] $newMap[$k]) } } + } + $majors = @($changed | Where-Object { $_.IsMajor }) + + # Bump the catalog version ONLY when something changed - no dependency change means no new version + # to publish. On a real run we rewrite the catalogDependencies and the version in place; dry run + # reports what WOULD change and writes nothing. + $hasChanges = ($changed.Count -gt 0) + $newVersion = if($hasChanges){ if($CatalogVersion){ $CatalogVersion } else { Get-NextPatchVersion $oldVersion } } else { $oldVersion } + if($hasChanges -and -not $DryRun){ + Update-CatalogDepsFile -Path $catalogYml -NewMap $newMap + $afterLines = Get-Content -LiteralPath $catalogYml + $bumped = $afterLines | ForEach-Object { + if($_ -match $VersionRx){ "$($Matches[1])$($Matches[2])$newVersion$($Matches[4])$($Matches[5])".TrimEnd() } else { $_ } + } + Write-Utf8NoBom-LF -Path $catalogYml -Content (($bumped -join "`n") + "`n") + Write-Info "Updated $($changed.Count) @ax/* dep(s); bumped catalog version $oldVersion -> $newVersion." + } elseif(-not $hasChanges){ + Write-Info 'No @ax/* dependency changes - catalog left unchanged (version NOT bumped).' + } + + Write-Host '' + Write-Host '================ CATALOG PLAN ================' -ForegroundColor Cyan + Write-Host (" @ax deps changed : {0} / {1}" -f $changed.Count, $newMap.Count) + Write-Host (" Major bumps : {0}" -f $majors.Count) + if($hasChanges){ Write-Host (" Catalog version : {0} -> {1}" -f $oldVersion, $newVersion) } + else { Write-Host (" Catalog version : {0} (unchanged - no dep updates)" -f $oldVersion) } + Write-Host '=============================================' -ForegroundColor Cyan + foreach($c in $changed){ Write-Info (" {0}: {1} -> {2}{3}" -f $c.Package, $c.From, $c.To, $(if($c.IsMajor){' [MAJOR]'}else{''})) } + if($majors.Count -gt 0){ Write-Warn "$($majors.Count) MAJOR-version bump(s) included - review before publishing." } + + # Sync consumers in the SAME phase - editing files needs no published catalog (only the cake verify + # build in Phase 2 does), so the catalog + all consumer edits land as one reviewable diff before + # publish. We pass the freshly-resolved map/version so dry-run preview is accurate even though the + # catalog file isn't written yet. Skipped entirely when nothing changed. + $sync = $null + if($hasChanges){ + Write-Host '' + $sync = Invoke-ConsumerSync -CatMap $newMap -CatVersion $newVersion + } + + # Report. + $md = New-Object System.Text.StringBuilder + [void]$md.AppendLine('# @ax catalog update - Phase 1 (refresh + sync)') + [void]$md.AppendLine('') + [void]$md.AppendLine("- Generated: $Stamp") + [void]$md.AppendLine("- Dry run: $([bool]$DryRun)") + [void]$md.AppendLine("- Prerelease: $([bool]$Prerelease)") + [void]$md.AppendLine("- Catalog version: $oldVersion -> $newVersion") + [void]$md.AppendLine("- @ax deps changed: $($changed.Count) of $($newMap.Count)") + [void]$md.AppendLine("- Major-version bumps: $($majors.Count)") + [void]$md.AppendLine("- Consumer edits: $(if($sync){$sync.TotalEdits}else{0})") + [void]$md.AppendLine('') + if($majors.Count -gt 0){ + [void]$md.AppendLine("## [!] Major-version bumps ($($majors.Count)) - review carefully") + [void]$md.AppendLine('| Package | From | To |') + [void]$md.AppendLine('|---|---|---|') + foreach($c in $majors){ [void]$md.AppendLine("| $($c.Package) | $($c.From) | $($c.To) |") } + [void]$md.AppendLine('') + } + [void]$md.AppendLine('## Changed @ax dependencies') + [void]$md.Append((Format-DiffTable -OldMap $oldMap -NewMap $newMap)) + if($sync -and $sync.TotalEdits -gt 0){ + [void]$md.AppendLine('') + [void]$md.AppendLine('## Consumer edits') + Add-ConsumerDiffMarkdown -Sb $md -Results $sync.Results + } + $payload = [PSCustomObject]@{ + phase='1-refresh-sync'; timestamp=$Stamp; dryRun=[bool]$DryRun; prerelease=[bool]$Prerelease + catalogVersionFrom=$oldVersion; catalogVersionTo=$newVersion; changed=$changed + consumerEdits=$(if($sync){$sync.TotalEdits}else{0}) + consumers=@(if($sync){ $sync.Results | ForEach-Object { [PSCustomObject]@{ file=(ConvertTo-RepoRelative $_.File); edits=$_.Edits } } }) + } + Write-Report -Stamp $Stamp -Phase 'phase1' -Payload $payload -MarkdownBody $md.ToString() | Out-Null + + Write-Host '' + if(-not $hasChanges){ + Write-Info 'All @ax/* dependencies already at their latest. Nothing to publish; no Phase 2 needed.' + return + } + if($DryRun){ + Write-Warn "[DRY RUN] $($changed.Count) @ax/* dep(s) would change; catalog would bump $oldVersion -> $newVersion; $($sync.TotalEdits) consumer edit(s)." + Write-Warn "[DRY RUN] Would then publish the catalog$(if($NoPublish){' (SKIPPED: -NoPublish)'}else{''}) and stop for build verification. Re-run without -DryRun to apply." + return + } + + # Real run with changes: publish the catalog automatically (per user request), unless -NoPublish. + if($NoPublish){ + Write-Info 'Catalog + consumers updated. Publish skipped (-NoPublish). NEXT STEPS:' + Write-Info " 1. Review the diff: git diff -- src/ax.catalog/apax.yml 'src/**/ctrl/apax.yml'" + Write-Info " 2. Publish the catalog: pwsh scripts/_pack_and_publish_catalog.ps1 (needs APAX_KEY, GH_USER, GH_TOKEN)" + Write-Info " 3. Verify the build: pwsh scripts/update-ax-catalog.ps1 -AfterPublish" + return + } + + Write-Host '' + if(Invoke-CatalogPublish){ + Write-Info "Catalog @inxton/ax.catalog $newVersion published." + Write-Info 'NEXT STEP - verify the build: pwsh scripts/update-ax-catalog.ps1 -AfterPublish' + } else { + Write-Err 'Automatic publish FAILED. The catalog + consumer edits are on disk but NOT published.' + Write-Err "Fix the cause (e.g. set APAX_KEY/GH_USER/GH_TOKEN), then run: pwsh scripts/_pack_and_publish_catalog.ps1" + Write-Err 'After a successful publish, run: pwsh scripts/update-ax-catalog.ps1 -AfterPublish' + exit 4 + } +} + +# =========================================================================== +# PHASE 2 - sync consumers + verify +# =========================================================================== + +# Rewrite one consumer file in place (or preview): sync @ax/* pins + catalog ref to $CatVersion/$CatMap. +# Returns a PSCustomObject with the file's applied edits. +function Update-ConsumerFile { + param([string]$Path, $CatMap, [string]$CatVersion) + $lines = Get-Content -LiteralPath $Path + $edits = New-Object System.Collections.ArrayList + $cur = $null + $out = for($i=0; $i -lt $lines.Count; $i++){ + $ln = $lines[$i] + if($ln -match '^[A-Za-z]'){ + if($ln -match '^([A-Za-z][\w\.]*)\s*:'){ $cur = $Matches[1] } + $ln; continue + } + if($cur -eq 'dependencies' -and $ln -match $AxDepRx){ + $pkg = $Matches[2]; $oldv = $Matches[5] + if($CatMap.Contains($pkg) -and $CatMap[$pkg] -ne $oldv){ + [void]$edits.Add([PSCustomObject]@{ Package=$pkg; From=$oldv; To=$CatMap[$pkg] }) + "$($Matches[1])$pkg$($Matches[3])$($Matches[4])$($CatMap[$pkg])$($Matches[6])$($Matches[7])".TrimEnd(); continue + } + $ln; continue + } + if($cur -eq 'catalogs' -and $ln -match $CatalogRefRx){ + $oldv = $Matches[5] + if($oldv -ne $CatVersion){ + [void]$edits.Add([PSCustomObject]@{ Package=$catalogPkg; From=$oldv; To=$CatVersion }) + "$($Matches[1])$($Matches[2])$($Matches[3])$($Matches[4])$CatVersion$($Matches[6])$($Matches[7])".TrimEnd(); continue + } + $ln; continue + } + $ln + } + if($edits.Count -gt 0 -and -not $DryRun){ + Write-Utf8NoBom-LF -Path $Path -Content (($out -join "`n") + "`n") + } + return [PSCustomObject]@{ File=$Path; Edits=@($edits) } +} + +# Discover catalog consumers and sync each one's @ax/* pins + `catalogs:` ref to the catalog. Applies +# edits in place (preview only when -DryRun). $CatMap/$CatVersion may be supplied explicitly (Phase 1 +# passes the freshly-resolved values so dry-run preview is accurate even though the catalog file is not +# written yet); when omitted they are read from the catalog file (Phase 2, post-publish). Returns the +# discovered consumers, per-file edit results, and the totals. +function Invoke-ConsumerSync { + param($CatMap, [string]$CatVersion) + if(-not $CatMap -or -not $CatVersion){ + $catLines = Get-Content -LiteralPath $catalogYml + if(-not $CatMap){ $CatMap = Get-AxDepsInSection -Lines $catLines -Section 'catalogDependencies' } + if(-not $CatVersion){ $CatVersion = Get-CatalogVersion -Lines $catLines } + } + if(-not $CatVersion){ Write-Err 'Could not determine catalog version for consumer sync.'; exit 2 } + + $consumerYmls = @(Get-CatalogConsumers) + if($consumerYmls.Count -eq 0){ Write-Err 'No catalog consumers discovered (no apax.yml references @inxton/ax.catalog).'; exit 2 } + Write-Info "Syncing $($consumerYmls.Count) consumer(s) to catalog @ $CatVersion ($($CatMap.Count) @ax/* deps):" + $results = foreach($c in $consumerYmls){ + $r = Update-ConsumerFile -Path $c -CatMap $CatMap -CatVersion $CatVersion + $rel = ConvertTo-RepoRelative $c + if($r.Edits.Count -gt 0){ + Write-Info " $rel : $($r.Edits.Count) edit(s)" + foreach($e in $r.Edits){ if($Detailed){ Write-Info (" {0}: {1} -> {2}" -f $e.Package,$e.From,$e.To) } } + } elseif($Detailed){ Write-Info " $rel : already in sync" } + $r + } + $totalEdits = (@($results) | ForEach-Object { $_.Edits.Count } | Measure-Object -Sum).Sum + return [PSCustomObject]@{ Consumers=$consumerYmls; Results=@($results); CatVersion=$CatVersion; TotalEdits=$totalEdits } +} + +# Append a per-consumer edit table section to a markdown StringBuilder. +function Add-ConsumerDiffMarkdown { + param([System.Text.StringBuilder]$Sb, $Results) + foreach($r in @($Results)){ + if($r.Edits.Count -eq 0){ continue } + [void]$Sb.AppendLine("### $(ConvertTo-RepoRelative $r.File) ($($r.Edits.Count))") + [void]$Sb.AppendLine('| Package | From | To |') + [void]$Sb.AppendLine('|---|---|---|') + foreach($e in $r.Edits){ [void]$Sb.AppendLine("| $($e.Package) | $($e.From) | $($e.To) |") } + [void]$Sb.AppendLine('') + } +} + +function Invoke-Phase2 { + param([string]$Stamp) + Write-Info '== PHASE 2: verify (consumers synced in Phase 1) ==' + if(-not (Test-Path -LiteralPath $catalogYml)){ Write-Err "Catalog not found: $catalogYml"; exit 2 } + + # Re-assert consumer sync as an idempotent guard: Phase 1 already synced them, but the catalog may + # have moved (e.g. a re-publish) or a new consumer may have appeared. Reads map/version from the + # (now-published) catalog file. Normally a no-op. + $sync = Invoke-ConsumerSync + if($sync.TotalEdits -gt 0){ Write-Warn "$($sync.TotalEdits) consumer edit(s) applied in Phase 2 (Phase 1 sync was incomplete or stale)." } + else { Write-Info 'Consumers already in sync with the catalog.' } + + $buildResult = if($DryRun){ 'not-run (dry run)' } else { Invoke-VerifyAndDiscardBuildNoise -Consumers $sync.Consumers } + + # Report. + $md = New-Object System.Text.StringBuilder + [void]$md.AppendLine('# @ax catalog update - Phase 2 (verify)') + [void]$md.AppendLine('') + [void]$md.AppendLine("- Generated: $Stamp") + [void]$md.AppendLine("- Dry run: $([bool]$DryRun)") + [void]$md.AppendLine("- Catalog version: $($sync.CatVersion)") + [void]$md.AppendLine("- Consumer edits (this phase): $($sync.TotalEdits)") + [void]$md.AppendLine("- Build result: **$buildResult**") + [void]$md.AppendLine('') + if($sync.TotalEdits -gt 0){ + [void]$md.AppendLine('## Consumer edits (Phase 2 guard)') + Add-ConsumerDiffMarkdown -Sb $md -Results $sync.Results + } + $payload = [PSCustomObject]@{ + phase='2-verify'; timestamp=$Stamp; dryRun=[bool]$DryRun; catalogVersion=$sync.CatVersion + build=$buildResult; consumerEditsThisPhase=$sync.TotalEdits + consumers=@($sync.Results | ForEach-Object { [PSCustomObject]@{ file=(ConvertTo-RepoRelative $_.File); edits=$_.Edits } }) + } + Write-Report -Stamp $Stamp -Phase 'phase2' -Payload $payload -MarkdownBody $md.ToString() | Out-Null + + Write-Host '' + Write-Host '================ PHASE 2 SUMMARY ================' -ForegroundColor Cyan + Write-Host (" Consumer edits : {0}" -f $sync.TotalEdits) + Write-Host (" Build : {0}" -f $buildResult) + Write-Host '=================================================' -ForegroundColor Cyan + + if($DryRun){ Write-Warn '[DRY RUN] Nothing written, no build run.'; return } + if($buildResult -like 'FAIL*'){ Write-Err 'Build verification FAILED - edits left staged for inspection.'; exit 1 } +} + +# Pre-build commit our files, run cake, then surgically discard build-produced changes and un-commit +# so our edits remain staged. Returns a build-result string. Never touches files that were already +# dirty before this run, and never runs `git clean`. +function Invoke-VerifyAndDiscardBuildNoise { + param([string[]]$Consumers) + if(-not (Test-CommandAvailable 'git')){ Write-Err 'git not found; cannot safely verify.'; return 'FAIL (git unavailable)' } + if(-not (Test-CommandAvailable 'dotnet')){ Write-Err 'dotnet not found; cannot build.'; return 'FAIL (dotnet unavailable)' } + + # Refuse to run mid-merge / detached HEAD. + $headRef = (& git -C $repoRoot symbolic-ref --quiet HEAD 2>$null) + if($LASTEXITCODE -ne 0){ Write-Err 'Detached HEAD or no branch; aborting Phase 2 git steps.'; return 'FAIL (detached HEAD)' } + if(Test-Path (Join-Path $repoRoot '.git/MERGE_HEAD')){ Write-Err 'Merge in progress; aborting.'; return 'FAIL (merge in progress)' } + + # Files that were already dirty BEFORE this run (excluding our own allowlist) must never be restored. + # Our edits are the source manifests only; ctrl/apax.yml and apax-lock.json are gitignored generated + # output and never appear in git status, so they need no special handling. + $allowlist = New-Object System.Collections.Generic.HashSet[string] ([StringComparer]::OrdinalIgnoreCase) + foreach($f in (@($catalogYml) + $Consumers)){ [void]$allowlist.Add((ConvertTo-RepoRelative $f)) } + + $preExistingDirty = New-Object System.Collections.Generic.HashSet[string] ([StringComparer]::OrdinalIgnoreCase) + foreach($line in (& git -C $repoRoot status --porcelain)){ + if($line.Length -lt 4){ continue } + $p = $line.Substring(3).Trim('"') + if($p -match ' -> '){ $p = ($p -split ' -> ')[-1].Trim('"') } # rename: keep destination + if(-not $allowlist.Contains($p)){ [void]$preExistingDirty.Add($p) } + } + if($Detailed -and $preExistingDirty.Count -gt 0){ + Write-Info "Protecting $($preExistingDirty.Count) pre-existing dirty path(s) from discard:" + foreach($p in $preExistingDirty){ Write-Info " $p" } + } + + # Pre-build commit of ONLY our files. + $addPaths = @($catalogYml) + $Consumers | ForEach-Object { ConvertTo-RepoRelative $_ } + & git -C $repoRoot add -- $addPaths + & git -C $repoRoot diff --cached --quiet + $committed = ($LASTEXITCODE -ne 0) # non-zero => there ARE staged changes + if($committed){ + & git -C $repoRoot commit -q -m @" +chore(catalog): update @ax deps + bump ax.catalog + +Automated by scripts/update-ax-catalog.ps1. + +Co-Authored-By: Claude Opus 4.8 (1M context) +"@ + if($LASTEXITCODE -ne 0){ Write-Err 'Pre-build commit failed.'; return 'FAIL (pre-build commit)' } + Write-Info 'Committed catalog + consumer edits (temporary; un-committed after verification).' + } else { + Write-Warn 'No catalog/consumer changes to commit; running build verification anyway.' + } + + # Verify with cake TESTS at level 2 (NOT pack). Level-2 runs apax install --catalog --strict + + # build per consumer and the L2 .NET test suite, which is what we want to prove the new catalog + # resolves and builds. We deliberately do NOT pack (--do-pack), so cake also won't stamp GitVersion + # SemVer into the manifests - the only remaining noise is apax install churn, handled below. + Write-Info 'Verifying: dotnet run --project cake/Build.csproj --do-test --test-level 2 -n' + & dotnet run --project $cakeProj -- --do-test --test-level 2 -n + $buildOk = ($LASTEXITCODE -eq 0) + + # Discard build/test-produced changes to TRACKED files (everything dirty vs HEAD that we did not + # already flag as pre-existing) - e.g. apax install churn during the test run. We never `git clean` + # (untracked files - incl. yours - are left alone). + $toRestore = New-Object System.Collections.ArrayList + foreach($p in (& git -C $repoRoot diff --name-only HEAD)){ + $pp = $p.Trim('"') + if(-not $preExistingDirty.Contains($pp)){ [void]$toRestore.Add($pp) } + } + if($toRestore.Count -gt 0){ + Write-Info "Discarding $($toRestore.Count) build-produced change(s) to tracked files." + & git -C $repoRoot checkout -- $toRestore + } + $newUntracked = @(& git -C $repoRoot ls-files --others --exclude-standard) | Where-Object { -not $preExistingDirty.Contains($_.Trim('"')) } + if($newUntracked.Count -gt 0){ + Write-Warn "$($newUntracked.Count) new untracked file(s) left by the build (NOT removed - clean manually if unwanted):" + foreach($u in ($newUntracked | Select-Object -First 20)){ Write-Warn " $u" } + } + + # Un-commit so our edits remain STAGED (build noise already discarded). + if($committed){ + & git -C $repoRoot reset --soft HEAD~1 + if($LASTEXITCODE -ne 0){ Write-Warn 'Could not soft-reset; the pre-build commit remains in history.' } + else { Write-Info 'Un-committed: catalog + consumer edits are now staged.' } + } + + if($buildOk){ return 'pass (test-level 2)' } else { return 'FAIL (cake test-level 2 - edits left staged)' } +} + +# =========================================================================== +# Main +# =========================================================================== +$stamp = (Get-Date).ToString('yyyy-MM-dd-HHmmss') +Write-Info "update-ax-catalog (afterPublish=$AfterPublish, dryRun=$DryRun, prerelease=$Prerelease)" +if($DryRun){ Write-Warn 'DRY RUN - no files, no git, no build.' } + +if($AfterPublish){ Invoke-Phase2 -Stamp $stamp } else { Invoke-Phase1 -Stamp $stamp } +exit 0 diff --git a/scripts/update-latest-deps.ps1 b/scripts/update-latest-deps.ps1 new file mode 100644 index 000000000..191802890 --- /dev/null +++ b/scripts/update-latest-deps.ps1 @@ -0,0 +1,692 @@ +#!/usr/bin/env pwsh +<# +.SYNOPSIS +Updates all (non-AXSharp) dependencies to their latest STABLE versions across NuGet, npm and dotnet tools. + +.DESCRIPTION +One command to bring the repo up to the latest stable third-party versions. It complements - and never +overlaps with - the two narrower updaters: + + * scripts/update_axsharp_versions.ps1 - owns AXSharp.*/Inxton.Operon.* (always skipped here) + * scripts/update-vulnerable-deps.ps1 - owns the "Security pins" ItemGroup (always skipped here) + +Scope: + + NuGet - rewrites entries (and the GitVersion.MsBuild ) in + Directory.Packages.props to the latest STABLE version from nuget.org. AXSharp/Operon/AXOpen + packages, the security-pin entries, and framework-tied packages (Microsoft.AspNetCore.*, + Microsoft.EntityFrameworkCore.*, Microsoft.Extensions.*, System.*, Microsoft.NET.ILLink.Tasks, + Microsoft.VisualStudio.Web.CodeGeneration.Design) are FROZEN to stay aligned with net10.0. + + npm - for the source package.json projects, rewrites declared ranges (preserving the ^/~ prefix) to + the latest stable from `npm outdated`, then runs `npm install` to refresh package-lock.json. + + tools - rewrites .config/dotnet-tools.json tool versions to latest stable (AXSharp.ix* skipped). + +GitVersion.MsBuild and gitversion.tool are resolved together and pinned to the SAME latest stable. + +"Latest" means latest STABLE: alpha/beta/rc are skipped. Major-version bumps ARE applied but flagged +prominently in the report (use -SkipMajor to exclude them). + +Default action is a DRY RUN - pass -Apply to write changes. With -Apply (and unless -SkipBuild) the full +cake build runs as verification; on failure the offending bump(s) are bisected out and only the green +remainder is kept. A timestamped Markdown + JSON report is written to scripts/reports/. With -CreatePR the +changes are committed to branch 'chore/update-latest-deps' off origin/dev and a PR is opened against dev. + +.PARAMETER Apply +Write changes. Without it the script previews only (dry run) and touches nothing. + +.PARAMETER NuGetOnly +Process NuGet (Directory.Packages.props) only. + +.PARAMETER NpmOnly +Process npm only. + +.PARAMETER ToolsOnly +Process dotnet tools only. + +.PARAMETER SkipMajor +Exclude major-version bumps (default: apply them and flag them in the report). + +.PARAMETER SkipBuild +Skip the cake build verification step (fast path; relies on manual review). + +.PARAMETER RollbackAllOnFailure +On build failure, revert every change instead of bisecting for a green subset. + +.PARAMETER MaxBisectBuilds +Cap on the number of full cake builds spent bisecting after an initial failure. Default 6. + +.PARAMETER CreatePR +Commit changes to branch 'chore/update-latest-deps' off origin/dev and open a PR against dev. Implies -Apply. + +.PARAMETER NpmProjects +Explicit list of package.json paths to process (relative to repo root or absolute). When omitted, +projects are discovered automatically under src/ (skipping bin/obj/ctrl/.apax/node_modules/wwwroot/dist). + +.PARAMETER Source +NuGet v3 feed used to look up available versions. Default nuget.org. + +.PARAMETER Token +Token for the NuGet feed (private feeds). Falls back to NUGET_TOKEN / GITHUB_PACKAGES_TOKEN / +GITHUB_TOKEN / GH_TOKEN. + +.PARAMETER Detailed +Verbose logging. + +.EXAMPLE +./update-latest-deps.ps1 # dry run, all ecosystems + +.EXAMPLE +./update-latest-deps.ps1 -NuGetOnly # dry run, NuGet only + +.EXAMPLE +./update-latest-deps.ps1 -Apply -SkipBuild # write changes, skip the (slow) cake build + +.EXAMPLE +./update-latest-deps.ps1 -CreatePR # apply, build-verify, open PR against dev +#> + +[CmdletBinding()] +param( + [switch]$Apply, + [switch]$NuGetOnly, + [switch]$NpmOnly, + [switch]$ToolsOnly, + [switch]$SkipMajor, + [switch]$SkipBuild, + [switch]$RollbackAllOnFailure, + [int]$MaxBisectBuilds = 6, + [switch]$CreatePR, + [string[]]$NpmProjects, + [string]$Source = 'https://api.nuget.org/v3/index.json', + [string]$Token, + [switch]$Detailed +) + +Set-StrictMode -Version Latest +$ErrorActionPreference = 'Stop' + +$scriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path +. "$scriptRoot/_deps-common.ps1" + +$repoRoot = Split-Path -Parent $scriptRoot +$propsPath = Join-Path $repoRoot 'Directory.Packages.props' +$toolsPath = Join-Path $repoRoot '.config/dotnet-tools.json' +$cakeProj = Join-Path $repoRoot 'cake/Build.csproj' + +# --------------------------------------------------------------------------- +# Validation & constants +# --------------------------------------------------------------------------- +if($CreatePR){ $Apply = $true } # -CreatePR implies writing changes +$DryRun = -not $Apply + +$onlyCount = @($NuGetOnly,$NpmOnly,$ToolsOnly | Where-Object { $_ }).Count +if($onlyCount -gt 1){ Write-Err '-NuGetOnly / -NpmOnly / -ToolsOnly are mutually exclusive.'; exit 1 } + +$doNuget = (-not $NpmOnly) -and (-not $ToolsOnly) +$doNpm = (-not $NuGetOnly) -and (-not $ToolsOnly) +$doTools = (-not $NuGetOnly) -and (-not $NpmOnly) + +# Feed auth: never send a token to the public nuget.org CDN (it 403s on authed cached responses). +# Resolve a token only for an explicitly-provided private -Source (or explicit -Token). +$IsPublicNuGet = ($Source -match 'api\.nuget\.org') +$feedToken = if($Token){ $Token } elseif(-not $IsPublicNuGet){ Resolve-FeedToken -Token $Token -Detailed:$Detailed } else { $null } + +# Owned by update_axsharp_versions.ps1 - never touched. +$AxSharpSkipPattern = '^(AXSharp|Inxton\.Operon|AXOpen)\b' +# Owned by update-vulnerable-deps.ps1 ("Security pins" ItemGroup) - never touched. +$SecurityPinIds = @('') #@('Snappier','System.Security.Cryptography.Xml') +# Frozen to stay aligned with net10.0 (see plan / interview). +$FrameworkFreezeExact = @('Microsoft.NET.ILLink.Tasks','Microsoft.VisualStudio.Web.CodeGeneration.Design') +$FrameworkFreezePrefixes = @('Microsoft.AspNetCore.','Microsoft.EntityFrameworkCore.','Microsoft.Extensions.','System.') +# GitVersion packages/tool are kept in sync with one another. +$GitVersionNuGetId = 'GitVersion.MsBuild' +$GitVersionToolId = 'gitversion.tool' + +# Source npm projects - discovered dynamically under src/, skipping generated/dependency +# copies (bin/obj/ctrl/.apax/node_modules/wwwroot). Override with -NpmProjects to be explicit. +function Get-NpmProjects { + $srcRoot = Join-Path $repoRoot 'src' + if(-not (Test-Path -LiteralPath $srcRoot)){ return @() } + $excludeRx = '[\\/](bin|obj|ctrl|\.apax|node_modules|wwwroot|dist|\.git)[\\/]' + Get-ChildItem -LiteralPath $srcRoot -Recurse -File -Filter 'package.json' -ErrorAction SilentlyContinue | + Where-Object { $_.FullName -notmatch $excludeRx } | + Select-Object -ExpandProperty FullName | + Sort-Object +} + +$NpmProjects = if($NpmProjects){ $NpmProjects | ForEach-Object { if([System.IO.Path]::IsPathRooted($_)){ $_ } else { Join-Path $repoRoot $_ } } } + else { Get-NpmProjects } + +# Accumulators for the report. +$Changes = New-Object System.Collections.ArrayList # applied/previewed bumps +$Frozen = New-Object System.Collections.ArrayList # id + reason +$Reverted = New-Object System.Collections.ArrayList # bumps removed by bisection +$ScanErrors = New-Object System.Collections.ArrayList +$BuildResult = 'not-run' + +# Captured original file contents (for bisection replay). file path -> original raw text. +$OriginalContent = @{} + +# --------------------------------------------------------------------------- +# Helpers +# --------------------------------------------------------------------------- +function Test-CommandAvailable { param([string]$Name) $null -ne (Get-Command $Name -ErrorAction SilentlyContinue) } + +function Test-IsMajorBump { + param([string]$From,[string]$To) + $f = ConvertTo-VersionRecord $From + $t = ConvertTo-VersionRecord $To + return ($t.Major -gt $f.Major) +} + +function Get-LatestStableVersion { + # Highest non-prerelease version of $PackageId on the feed, or $null. + param([string]$PackageId,$FeedCtx) + $versions = @() + try { $versions = Get-PackageVersionsFromFeed -PkgBase $FeedCtx.PkgBase -Headers $FeedCtx.Headers -PackageId $PackageId } + catch { if($Detailed){ Write-Warn "feed lookup failed for ${PackageId}: $($_.Exception.Message)" }; return $null } + if(-not $versions -or @($versions).Count -eq 0){ return $null } + $stable = @($versions | Where-Object { -not (Test-IsPrerelease $_) }) + if($stable.Count -eq 0){ return $null } + $best = $stable[0] + foreach($v in $stable){ if(Test-VersionGreater $v $best){ $best = $v } } + return $best +} + +function Get-NuGetDisposition { + # Returns 'update' or a 'freeze-*' / 'skip-*' reason for a package id. + param([string]$Id) + if($Id -match $AxSharpSkipPattern){ return 'skip-axsharp (owned by update_axsharp_versions.ps1)' } + if($SecurityPinIds -contains $Id){ return 'skip-security-pin (owned by update-vulnerable-deps.ps1)' } + if($FrameworkFreezeExact -contains $Id){ return 'freeze-framework (net10.0-tied)' } + foreach($p in $FrameworkFreezePrefixes){ if($Id.StartsWith($p)){ return 'freeze-framework (net10.0-tied)' } } + return 'update' +} + +# --------------------------------------------------------------------------- +# Change application (replayable from captured original content) +# --------------------------------------------------------------------------- +function Apply-ChangeToContent { + # Applies a single change to the supplied file content and returns the new content. + param([string]$Content,$Change) + $idEsc = [regex]::Escape($Change.Id) + switch($Change.Kind){ + 'props-packageversion' { + $rx = "(]*\bInclude=`"$idEsc`"[^>]*\bVersion=`")[^`"]*(`")" + return [regex]::Replace($Content,$rx,"`${1}$($Change.To)`${2}",1) + } + 'props-globalref' { + $rx = "(]*\bInclude=`"$idEsc`"[^>]*\bVersion=`")[^`"]*(`")" + return [regex]::Replace($Content,$rx,"`${1}$($Change.To)`${2}",1) + } + 'tool' { + $rx = "(`"$idEsc`"\s*:\s*\{[^{}]*?`"version`"\s*:\s*`")[^`"]+(`")" + return [System.Text.RegularExpressions.Regex]::Replace( + $Content,$rx,"`${1}$($Change.To)`${2}", + [System.Text.RegularExpressions.RegexOptions]::Singleline) + } + 'npm' { + # Preserve any leading range operator (^, ~, >=, etc.) on the declared range. + $rx = "(`"$idEsc`"\s*:\s*`")([^`"]*)(`")" + return [regex]::Replace($Content,$rx,{ + param($m) + $old = $m.Groups[2].Value + $prefix = '' + if($old -match '^([\^~>=<\s]*)'){ $prefix = $Matches[1] } + $m.Groups[1].Value + $prefix + $Change.To + $m.Groups[3].Value + },1) + } + default { return $Content } + } +} + +function Write-FileSet { + # Rebuilds every affected file from its captured ORIGINAL content, applying only $ActiveChanges. + # Returns the list of npm directories whose package.json changed (caller refreshes their lock). + param($ActiveChanges) + $byFile = $ActiveChanges | Group-Object -Property File + $npmDirs = New-Object System.Collections.ArrayList + foreach($g in $byFile){ + $file = $g.Name + if(-not $OriginalContent.ContainsKey($file)){ continue } + $content = $OriginalContent[$file] + foreach($c in $g.Group){ + $content = Apply-ChangeToContent -Content $content -Change $c + if($c.Ecosystem -eq 'npm'){ $dir = Split-Path -Parent $file; if(-not $npmDirs.Contains($dir)){ [void]$npmDirs.Add($dir) } } + } + Write-Utf8NoBom-LF -Path $file -Content $content + } + # Files that had ALL their changes removed must be restored to original too. + foreach($file in $OriginalContent.Keys){ + if(-not ($byFile | Where-Object { $_.Name -eq $file })){ + Write-Utf8NoBom-LF -Path $file -Content $OriginalContent[$file] + } + } + return $npmDirs +} + +function Update-NpmLockfiles { + param($NpmDirs) + foreach($dir in $NpmDirs){ + if($Detailed){ Write-Info " npm install (refresh lockfile): $dir" } + Push-Location $dir + try { & npm install --no-audit --no-fund *> $null } + catch { [void]$ScanErrors.Add("npm install failed in ${dir}: $($_.Exception.Message)") } + finally { Pop-Location } + } +} + +# --------------------------------------------------------------------------- +# Scanners (populate $Changes / $Frozen; capture originals) +# --------------------------------------------------------------------------- +function Invoke-NuGetScan { + param($FeedCtx) + Write-Info 'Scanning NuGet (Directory.Packages.props)...' + if(-not (Test-Path $propsPath)){ [void]$ScanErrors.Add('Directory.Packages.props not found'); return } + $content = Get-Content -LiteralPath $propsPath -Raw + $OriginalContent[$propsPath] = $content + + $pvMatches = [regex]::Matches($content,']*\bInclude="([^"]+)"[^>]*\bVersion="([^"]+)"') + $grMatches = [regex]::Matches($content,']*\bInclude="([^"]+)"[^>]*\bVersion="([^"]+)"') + + foreach($m in @($pvMatches) + @($grMatches)){ + $id = $m.Groups[1].Value + $cur = $m.Groups[2].Value + $kind = if($m.Value -like '*GlobalPackageReference*'){ 'props-globalref' } else { 'props-packageversion' } + + # GitVersion handled together below. + if($id -eq $GitVersionNuGetId){ continue } + + $disp = Get-NuGetDisposition $id + if($disp -ne 'update'){ [void]$Frozen.Add([PSCustomObject]@{ Ecosystem='nuget'; Id=$id; Current=$cur; Reason=$disp }); continue } + + $latest = Get-LatestStableVersion -PackageId $id -FeedCtx $FeedCtx + if(-not $latest){ [void]$Frozen.Add([PSCustomObject]@{ Ecosystem='nuget'; Id=$id; Current=$cur; Reason='no stable version on feed' }); continue } + if(-not (Test-VersionGreater $latest $cur)){ if($Detailed){ Write-Info " $id already latest ($cur)" }; continue } + + $isMajor = Test-IsMajorBump $cur $latest + if($isMajor -and $SkipMajor){ [void]$Frozen.Add([PSCustomObject]@{ Ecosystem='nuget'; Id=$id; Current=$cur; Reason="major bump to $latest skipped (-SkipMajor)" }); continue } + + [void]$Changes.Add([PSCustomObject]@{ Ecosystem='nuget'; Id=$id; From=$cur; To=$latest; IsMajor=$isMajor; Kind=$kind; File=$propsPath }) + Write-Info (" {0}: {1} -> {2}{3}" -f $id,$cur,$latest,$(if($isMajor){' [MAJOR]'}else{''})) + } +} + +function Resolve-GitVersionSync { + # Resolves one latest-stable GitVersion across MsBuild pkg + dotnet tool and queues both bumps. + param($FeedCtx) + if(-not (Test-Path $propsPath)){ return } + $propsRaw = $OriginalContent[$propsPath] + if(-not $propsRaw){ $propsRaw = Get-Content -LiteralPath $propsPath -Raw; $OriginalContent[$propsPath] = $propsRaw } + + $curMsb = $null + $m = [regex]::Match($propsRaw,"]*\bInclude=`"$([regex]::Escape($GitVersionNuGetId))`"[^>]*\bVersion=`"([^`"]+)`"") + if($m.Success){ $curMsb = $m.Groups[1].Value } + + $curTool = $null + if(Test-Path $toolsPath){ + $toolsRaw = $OriginalContent[$toolsPath] + if(-not $toolsRaw){ $toolsRaw = Get-Content -LiteralPath $toolsPath -Raw; $OriginalContent[$toolsPath] = $toolsRaw } + $tm = [regex]::Match($toolsRaw,"`"$([regex]::Escape($GitVersionToolId))`"\s*:\s*\{[^{}]*?`"version`"\s*:\s*`"([^`"]+)`"",[System.Text.RegularExpressions.RegexOptions]::Singleline) + if($tm.Success){ $curTool = $tm.Groups[1].Value } + } + + $latestMsb = Get-LatestStableVersion -PackageId $GitVersionNuGetId -FeedCtx $FeedCtx + $latestTool = Get-LatestStableVersion -PackageId $GitVersionToolId -FeedCtx $FeedCtx + $synced = $latestMsb + if($latestTool -and (Test-VersionGreater $latestTool $synced)){ $synced = $latestTool } + if(-not $synced){ Write-Warn 'Could not resolve a latest stable GitVersion; leaving as-is.'; return } + + if($doNuget -and $curMsb -and (Test-VersionGreater $synced $curMsb)){ + $isMajor = Test-IsMajorBump $curMsb $synced + if(-not ($isMajor -and $SkipMajor)){ + [void]$Changes.Add([PSCustomObject]@{ Ecosystem='nuget'; Id=$GitVersionNuGetId; From=$curMsb; To=$synced; IsMajor=$isMajor; Kind='props-globalref'; File=$propsPath }) + Write-Info (" {0}: {1} -> {2} (GitVersion sync){3}" -f $GitVersionNuGetId,$curMsb,$synced,$(if($isMajor){' [MAJOR]'}else{''})) + } else { [void]$Frozen.Add([PSCustomObject]@{ Ecosystem='nuget'; Id=$GitVersionNuGetId; Current=$curMsb; Reason="major bump to $synced skipped (-SkipMajor)" }) } + } + if($doTools -and $curTool -and (Test-VersionGreater $synced $curTool)){ + $isMajor = Test-IsMajorBump $curTool $synced + if(-not ($isMajor -and $SkipMajor)){ + [void]$Changes.Add([PSCustomObject]@{ Ecosystem='tool'; Id=$GitVersionToolId; From=$curTool; To=$synced; IsMajor=$isMajor; Kind='tool'; File=$toolsPath }) + Write-Info (" {0}: {1} -> {2} (GitVersion sync){3}" -f $GitVersionToolId,$curTool,$synced,$(if($isMajor){' [MAJOR]'}else{''})) + } else { [void]$Frozen.Add([PSCustomObject]@{ Ecosystem='tool'; Id=$GitVersionToolId; Current=$curTool; Reason="major bump to $synced skipped (-SkipMajor)" }) } + } +} + +function Invoke-ToolsScan { + param($FeedCtx) + Write-Info 'Scanning dotnet tools (.config/dotnet-tools.json)...' + if(-not (Test-Path $toolsPath)){ [void]$ScanErrors.Add('.config/dotnet-tools.json not found'); return } + $raw = $OriginalContent[$toolsPath] + if(-not $raw){ $raw = Get-Content -LiteralPath $toolsPath -Raw; $OriginalContent[$toolsPath] = $raw } + try { $obj = $raw | ConvertFrom-Json -ErrorAction Stop } catch { [void]$ScanErrors.Add('tools JSON parse failed'); return } + if(-not $obj.tools){ [void]$ScanErrors.Add("tools JSON missing 'tools'"); return } + + foreach($name in $obj.tools.PSObject.Properties.Name){ + if($name -like 'AXSharp.*' -or $name -like 'Inxton.Operon.*'){ [void]$Frozen.Add([PSCustomObject]@{ Ecosystem='tool'; Id=$name; Current=$obj.tools.$name.version; Reason='skip-axsharp (owned by update_axsharp_versions.ps1)' }); continue } + if($name -eq $GitVersionToolId){ continue } # handled by Resolve-GitVersionSync + $cur = $obj.tools.$name.version + $latest = Get-LatestStableVersion -PackageId $name -FeedCtx $FeedCtx + if(-not $latest){ [void]$Frozen.Add([PSCustomObject]@{ Ecosystem='tool'; Id=$name; Current=$cur; Reason='no stable version on feed' }); continue } + if(-not (Test-VersionGreater $latest $cur)){ if($Detailed){ Write-Info " $name already latest ($cur)" }; continue } + $isMajor = Test-IsMajorBump $cur $latest + if($isMajor -and $SkipMajor){ [void]$Frozen.Add([PSCustomObject]@{ Ecosystem='tool'; Id=$name; Current=$cur; Reason="major bump to $latest skipped (-SkipMajor)" }); continue } + [void]$Changes.Add([PSCustomObject]@{ Ecosystem='tool'; Id=$name; From=$cur; To=$latest; IsMajor=$isMajor; Kind='tool'; File=$toolsPath }) + Write-Info (" {0}: {1} -> {2}{3}" -f $name,$cur,$latest,$(if($isMajor){' [MAJOR]'}else{''})) + } +} + +function Invoke-NpmScan { + Write-Info 'Scanning npm projects...' + if(-not (Test-CommandAvailable 'npm')){ Write-Err 'npm not found on PATH.'; [void]$ScanErrors.Add('npm not found'); return } + foreach($pkgJson in $NpmProjects){ + if(-not (Test-Path -LiteralPath $pkgJson)){ if($Detailed){ Write-Warn "missing: $pkgJson" }; continue } + $dir = Split-Path -Parent $pkgJson + $name = (Resolve-Path -LiteralPath $dir).Path.Replace((Resolve-Path $repoRoot).Path,'').TrimStart('\','/') + Write-Info " $name" + $OriginalContent[$pkgJson] = Get-Content -LiteralPath $pkgJson -Raw + Push-Location $dir + try { + if(-not (Test-Path 'node_modules')){ + if($Detailed){ Write-Info " npm install (no node_modules)" } + & npm install --no-audit --no-fund *> $null + } + $raw = & npm outdated --json 2>$null | Out-String + if(-not $raw.Trim()){ if($Detailed){ Write-Info " up to date" }; Pop-Location; continue } + $parsed = $null; try { $parsed = $raw | ConvertFrom-Json } catch { [void]$ScanErrors.Add("npm outdated unparseable: $name"); Pop-Location; continue } + if(-not $parsed){ Pop-Location; continue } + foreach($p in $parsed.PSObject.Properties){ + $pkgName = $p.Name + $info = $p.Value + if($info -is [System.Object[]]){ $info = $info[0] } # multiple entries -> take first + $cur = if($info.PSObject.Properties.Name -contains 'current'){ $info.current } else { $null } + $latest = if($info.PSObject.Properties.Name -contains 'latest'){ $info.latest } else { $null } + if(-not $cur -or -not $latest){ continue } # not installed / no candidate + if(Test-IsPrerelease $latest){ continue } # stable only + if(-not (Test-VersionGreater $latest $cur)){ continue } + $isMajor = Test-IsMajorBump $cur $latest + if($isMajor -and $SkipMajor){ [void]$Frozen.Add([PSCustomObject]@{ Ecosystem='npm'; Id="$name/$pkgName"; Current=$cur; Reason="major bump to $latest skipped (-SkipMajor)" }); continue } + [void]$Changes.Add([PSCustomObject]@{ Ecosystem='npm'; Id=$pkgName; Project=$name; From=$cur; To=$latest; IsMajor=$isMajor; Kind='npm'; File=$pkgJson }) + Write-Info (" {0}: {1} -> {2}{3}" -f $pkgName,$cur,$latest,$(if($isMajor){' [MAJOR]'}else{''})) + } + } catch { [void]$ScanErrors.Add("npm scan error in ${name}: $($_.Exception.Message)") } + finally { Pop-Location } + } +} + +# --------------------------------------------------------------------------- +# Build verification + bisection +# --------------------------------------------------------------------------- +function Invoke-CakeBuild { + if(-not (Test-CommandAvailable 'dotnet')){ Write-Err 'dotnet CLI not found; cannot build.'; return $false } + Write-Info 'Running full cake build (dotnet run --project cake/Build.csproj) ...' + & dotnet run --project $cakeProj + return ($LASTEXITCODE -eq 0) +} + +function Invoke-BisectGreenSubset { + # ddmin-style: remove minimal change subsets until the build is green, bounded by $MaxBisectBuilds. + # Mutates the working tree to the green subset; records removed changes in $script:Reverted. + $builds = 0 + $active = @($Changes) + $n = 2 + Write-Warn "Build failed with all $($active.Count) change(s). Bisecting for a green subset (max $MaxBisectBuilds builds)..." + while($builds -lt $MaxBisectBuilds -and $active.Count -gt 1){ + $chunkSize = [Math]::Ceiling($active.Count / $n) + $removedSomething = $false + for($i=0; $i -lt $active.Count; $i += $chunkSize){ + $chunk = $active[$i..([Math]::Min($i+$chunkSize-1,$active.Count-1))] + $trial = $active | Where-Object { $chunk -notcontains $_ } + if(@($trial).Count -eq 0){ continue } + $dirs = Write-FileSet -ActiveChanges $trial + Update-NpmLockfiles -NpmDirs $dirs + $builds++ + Write-Info " bisect build $builds/$MaxBisectBuilds : trying $((@($trial)).Count) of $($active.Count) changes" + if(Invoke-CakeBuild){ $active = @($trial); $n = [Math]::Max($n-1,2); $removedSomething = $true; break } + if($builds -ge $MaxBisectBuilds){ break } + } + if(-not $removedSomething){ + if($n -ge $active.Count){ break } + $n = [Math]::Min($n*2,$active.Count) + } + } + # Record what got dropped and lock in the surviving subset. + $kept = @($active) + foreach($c in $Changes){ if($kept -notcontains $c){ [void]$Reverted.Add($c) } } + $dirs = Write-FileSet -ActiveChanges $kept + Update-NpmLockfiles -NpmDirs $dirs + if($kept.Count -gt 0 -and $builds -lt $MaxBisectBuilds){ + $builds++ + Write-Info " bisect build $builds : confirming surviving subset ($($kept.Count) change(s))" + $script:BuildResult = if(Invoke-CakeBuild){ 'pass (after bisection)' } else { 'FAIL (bisection exhausted - manual review)' } + } else { + $script:BuildResult = "indeterminate (bisection hit -MaxBisectBuilds=$MaxBisectBuilds)" + } +} + +# --------------------------------------------------------------------------- +# Report +# --------------------------------------------------------------------------- +function Write-Report { + param([string]$Stamp) + $reportsDir = Join-Path $scriptRoot 'reports' + if(-not (Test-Path $reportsDir)){ New-Item -ItemType Directory -Path $reportsDir -Force | Out-Null } + $mdPath = Join-Path $reportsDir "latest-deps-report-$Stamp.md" + $jsonPath = Join-Path $reportsDir "latest-deps-report-$Stamp.json" + + $applied = @($Changes | Where-Object { $Reverted -notcontains $_ }) + $majors = @($applied | Where-Object { $_.IsMajor }) + + $payload = [PSCustomObject]@{ + timestamp = $Stamp + dryRun = [bool]$DryRun + skipMajor = [bool]$SkipMajor + ecosystems = @{ nuget=[bool]$doNuget; npm=[bool]$doNpm; tools=[bool]$doTools } + build = $BuildResult + applied = $applied + reverted = $Reverted + frozen = $Frozen + majors = $majors + scanErrors = $ScanErrors + } + Write-Utf8NoBom-LF -Path $jsonPath -Content ($payload | ConvertTo-Json -Depth 8) + + $sb = New-Object System.Text.StringBuilder + [void]$sb.AppendLine('# Latest-dependency update report') + [void]$sb.AppendLine('') + [void]$sb.AppendLine("- Generated: $Stamp") + [void]$sb.AppendLine("- Dry run: $([bool]$DryRun)") + [void]$sb.AppendLine("- Skip major: $([bool]$SkipMajor)") + [void]$sb.AppendLine("- Ecosystems: NuGet=$doNuget, npm=$doNpm, tools=$doTools") + [void]$sb.AppendLine("- Build result: **$BuildResult**") + [void]$sb.AppendLine('') + + if($majors.Count -gt 0){ + [void]$sb.AppendLine("## [!] Major-version bumps ($($majors.Count)) - review carefully") + [void]$sb.AppendLine('| Ecosystem | Package | From | To |') + [void]$sb.AppendLine('|---|---|---|---|') + foreach($c in $majors){ [void]$sb.AppendLine("| $($c.Ecosystem) | $($c.Id) | $($c.From) | $($c.To) |") } + [void]$sb.AppendLine('') + } + + [void]$sb.AppendLine("## NuGet bumped ($(@($applied | Where-Object { $_.Ecosystem -eq 'nuget' }).Count))") + [void]$sb.AppendLine('| Package | From | To | Major? |') + [void]$sb.AppendLine('|---|---|---|---|') + foreach($c in ($applied | Where-Object { $_.Ecosystem -eq 'nuget' })){ [void]$sb.AppendLine("| $($c.Id) | $($c.From) | $($c.To) | $(if($c.IsMajor){'YES'}else{''}) |") } + [void]$sb.AppendLine('') + + [void]$sb.AppendLine("## npm bumped ($(@($applied | Where-Object { $_.Ecosystem -eq 'npm' }).Count))") + [void]$sb.AppendLine('| Project | Package | From | To | Major? |') + [void]$sb.AppendLine('|---|---|---|---|---|') + foreach($c in ($applied | Where-Object { $_.Ecosystem -eq 'npm' })){ [void]$sb.AppendLine("| $($c.Project) | $($c.Id) | $($c.From) | $($c.To) | $(if($c.IsMajor){'YES'}else{''}) |") } + [void]$sb.AppendLine('') + + [void]$sb.AppendLine("## Tools bumped ($(@($applied | Where-Object { $_.Ecosystem -eq 'tool' }).Count))") + [void]$sb.AppendLine('| Tool | From | To |') + [void]$sb.AppendLine('|---|---|---|') + foreach($c in ($applied | Where-Object { $_.Ecosystem -eq 'tool' })){ [void]$sb.AppendLine("| $($c.Id) | $($c.From) | $($c.To) |") } + [void]$sb.AppendLine('') + + if($Reverted.Count -gt 0){ + [void]$sb.AppendLine("## Reverted by build bisection ($($Reverted.Count))") + [void]$sb.AppendLine('| Ecosystem | Package | From | To |') + [void]$sb.AppendLine('|---|---|---|---|') + foreach($c in $Reverted){ [void]$sb.AppendLine("| $($c.Ecosystem) | $($c.Id) | $($c.From) | $($c.To) |") } + [void]$sb.AppendLine('') + } + + [void]$sb.AppendLine("## Frozen / skipped ($($Frozen.Count))") + [void]$sb.AppendLine('| Ecosystem | Package | Current | Reason |') + [void]$sb.AppendLine('|---|---|---|---|') + foreach($f in $Frozen){ [void]$sb.AppendLine("| $($f.Ecosystem) | $($f.Id) | $($f.Current) | $($f.Reason) |") } + [void]$sb.AppendLine('') + + if($ScanErrors.Count -gt 0){ + [void]$sb.AppendLine('## Scan errors') + foreach($e in $ScanErrors){ [void]$sb.AppendLine("- $e") } + } + Write-Utf8NoBom-LF -Path $mdPath -Content $sb.ToString() + Write-Info "Report: $mdPath" + return $mdPath +} + +# --------------------------------------------------------------------------- +# Commit + PR +# --------------------------------------------------------------------------- +function Invoke-CreatePR { + param([string]$ReportPath) + if(-not (Test-CommandAvailable 'git')){ Write-Err 'git not found; cannot create PR.'; return } + if(-not (Test-CommandAvailable 'gh')){ Write-Err 'gh CLI not found; cannot open PR.'; return } + + $branch = 'chore/update-latest-deps' + Write-Info "Creating branch '$branch' off origin/dev and opening PR..." + + & git -C $repoRoot fetch origin dev --quiet + & git -C $repoRoot stash push -u -m 'latest-deps-wip' *> $null + $stashed = ($LASTEXITCODE -eq 0) + & git -C $repoRoot switch -C $branch origin/dev + if($LASTEXITCODE -ne 0){ Write-Err "Failed to create branch $branch."; if($stashed){ & git -C $repoRoot stash pop *> $null }; return } + if($stashed){ + & git -C $repoRoot stash pop + if($LASTEXITCODE -ne 0){ Write-Err 'Stash pop conflicted; resolve manually. Aborting PR.'; return } + } + + & git -C $repoRoot add -- 'Directory.Packages.props' '.config/dotnet-tools.json' '**/package.json' '**/package-lock.json' + & git -C $repoRoot commit -m @' +chore(deps): update dependencies to latest stable + +Automated by scripts/update-latest-deps.ps1. + +Co-Authored-By: Claude Opus 4.8 (1M context) +'@ + if($LASTEXITCODE -ne 0){ Write-Warn 'Nothing to commit (no changes staged). Skipping PR.'; return } + + & git -C $repoRoot push -u origin $branch + if($LASTEXITCODE -ne 0){ Write-Err 'git push failed.'; return } + + $applied = @($Changes | Where-Object { $Reverted -notcontains $_ }) + $bumpLines = ($applied | ForEach-Object { "- $($_.Ecosystem) $($_.Id): $($_.From) -> $($_.To)$(if($_.IsMajor){' (MAJOR)'}else{''})" }) -join "`n" + $majorList = ($applied | Where-Object { $_.IsMajor } | ForEach-Object { "- $($_.Ecosystem) $($_.Id): $($_.From) -> $($_.To)" }) -join "`n" + $revLines = ($Reverted | ForEach-Object { "- $($_.Ecosystem) $($_.Id): $($_.From) -> $($_.To)" }) -join "`n" + $body = @" +Automated update of (non-AXSharp) dependencies to their latest stable versions. + +Build verification: $BuildResult + +## Bumped ($($applied.Count)) +$bumpLines + +## [!] Major-version bumps +$(if($majorList){ $majorList } else { '_none_' }) + +## Reverted by build bisection +$(if($revLines){ $revLines } else { '_none_' }) + +See the attached report ($([System.IO.Path]::GetFileName($ReportPath))) for frozen/skipped detail. + +🤖 Generated with [Claude Code](https://claude.com/claude-code) +"@ + & gh pr create --base dev --head $branch --title 'chore(deps): update dependencies to latest stable' --body $body + if($LASTEXITCODE -ne 0){ Write-Err 'gh pr create failed.' } else { Write-Info 'PR opened against dev.' } +} + +# --------------------------------------------------------------------------- +# Main +# --------------------------------------------------------------------------- +$stamp = (Get-Date).ToString('yyyy-MM-dd-HHmmss') +Write-Info "update-latest-deps (apply=$Apply, dryRun=$DryRun, nuget=$doNuget, npm=$doNpm, tools=$doTools, skipMajor=$SkipMajor)" +if($DryRun){ Write-Warn 'DRY RUN - no files will be changed. Pass -Apply to write.' } + +$feedCtx = $null +if($doNuget -or $doTools){ + try { $feedCtx = Get-FeedContext -Feed $Source -User $null -Tok $feedToken } catch { Write-Err "Could not initialise NuGet feed: $($_.Exception.Message)"; exit 2 } +} + +if($doNuget){ Invoke-NuGetScan -FeedCtx $feedCtx } +if($doTools){ Invoke-ToolsScan -FeedCtx $feedCtx } +if($doNuget -or $doTools){ Resolve-GitVersionSync -FeedCtx $feedCtx } +if($doNpm){ Invoke-NpmScan } + +Write-Host '' +Write-Host '================ PLAN ================' -ForegroundColor Cyan +Write-Host (" Changes : {0}" -f $Changes.Count) +Write-Host (" Major : {0}" -f @($Changes | Where-Object { $_.IsMajor }).Count) +Write-Host (" Frozen : {0}" -f $Frozen.Count) +Write-Host (" Errors : {0}" -f $ScanErrors.Count) +Write-Host '=====================================' -ForegroundColor Cyan + +if($DryRun){ + Write-Warn '[DRY RUN] No changes written. Review the report below.' + $reportPath = Write-Report -Stamp $stamp + if($ScanErrors.Count -gt 0){ Write-Warn "$($ScanErrors.Count) scan error(s) - see report." } + exit 0 +} + +if($Changes.Count -eq 0){ + Write-Info 'Nothing to update; everything already at latest stable.' + Write-Report -Stamp $stamp | Out-Null + exit 0 +} + +# Apply everything, then verify. +$dirs = Write-FileSet -ActiveChanges @($Changes) +Update-NpmLockfiles -NpmDirs $dirs +Write-Info "Applied $($Changes.Count) change(s) to the working tree." + +if(-not $SkipBuild){ + if(Invoke-CakeBuild){ + $BuildResult = 'pass' + Write-Info 'Build passed with all changes.' + } elseif($RollbackAllOnFailure){ + Write-Warn 'Build failed; -RollbackAllOnFailure set, reverting everything.' + foreach($c in $Changes){ [void]$Reverted.Add($c) } + Write-FileSet -ActiveChanges @() | Out-Null + $BuildResult = 'FAIL (all changes rolled back)' + } else { + Invoke-BisectGreenSubset + } +} else { + $BuildResult = 'skipped (-SkipBuild)' + Write-Warn 'Build verification skipped (-SkipBuild).' +} + +$reportPath = Write-Report -Stamp $stamp + +Write-Host '' +Write-Host '================ SUMMARY ================' -ForegroundColor Cyan +Write-Host (" Applied : {0}" -f @($Changes | Where-Object { $Reverted -notcontains $_ }).Count) +Write-Host (" Reverted : {0}" -f $Reverted.Count) +Write-Host (" Frozen : {0}" -f $Frozen.Count) +Write-Host (" Build : {0}" -f $BuildResult) +Write-Host (" Errors : {0}" -f $ScanErrors.Count) +Write-Host '========================================' -ForegroundColor Cyan + +if($CreatePR){ + if(@($Changes | Where-Object { $Reverted -notcontains $_ }).Count -gt 0){ Invoke-CreatePR -ReportPath $reportPath } + else { Write-Warn 'No surviving changes; skipping PR creation.' } +} + +if($BuildResult -like 'FAIL*'){ exit 1 } +exit 0 diff --git a/scripts/update-vulnerable-deps-npm-app.ps1 b/scripts/update-vulnerable-deps-npm-app.ps1 deleted file mode 100644 index b2ee3c31f..000000000 --- a/scripts/update-vulnerable-deps-npm-app.ps1 +++ /dev/null @@ -1,140 +0,0 @@ -#!/usr/bin/env pwsh -<# -.SYNOPSIS -Updates vulnerable npm dependencies in all directories matching the pattern **/app/ix-blazor/ - -.DESCRIPTION -This script finds all directories matching the pattern **/app/ix-blazor/ and runs npm audit fix -to automatically fix identified vulnerabilities. - -.PARAMETER DryRun -If specified, only shows what would be done without making actual changes. - -.PARAMETER Force -If specified, bypasses confirmation prompts. - -.EXAMPLE -./update-vulnerable-deps.ps1 -./update-vulnerable-deps.ps1 -DryRun -./update-vulnerable-deps.ps1 -Force -#> - -param( - [switch]$DryRun, - [switch]$Force -) - -$ErrorActionPreference = "Stop" - -# Get the script's directory -$scriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path - -# Find all directories matching **/app/ix-blazor/ -Write-Host "Searching for directories matching pattern '**/app/ix-blazor/'..." -ForegroundColor Cyan - -$targetDirs = @() -$appDirs = Get-ChildItem -Path $scriptRoot -Recurse -Filter "app" -Directory -ErrorAction SilentlyContinue - -foreach ($appDir in $appDirs) { - $ixBlazerPath = Join-Path -Path $appDir.FullName -ChildPath "ix-blazor" - - if (Test-Path -Path $ixBlazerPath -PathType Container) { - $packageJsonPath = Join-Path -Path $ixBlazerPath -ChildPath "package.json" - - if (Test-Path -Path $packageJsonPath -PathType Leaf) { - $targetDirs += @{ - Path = $ixBlazerPath - PackageJson = $packageJsonPath - } - } - } -} - -if ($targetDirs.Count -eq 0) { - Write-Host "No directories matching '**/app/ix-blazor/' with package.json found." -ForegroundColor Yellow - exit 0 -} - -Write-Host "Found $($targetDirs.Count) directory/directories to process:" -ForegroundColor Green -foreach ($dir in $targetDirs) { - Write-Host " - $($dir.Path)" -ForegroundColor Gray -} - -if (-not $Force) { - Write-Host "" - $confirmation = Read-Host "Continue with npm audit fix? (Y/n)" - if ($confirmation -and $confirmation.ToLower() -ne 'y') { - Write-Host "Operation cancelled." -ForegroundColor Yellow - exit 0 - } -} - -# Process each directory -$successCount = 0 -$failureCount = 0 - -foreach ($dir in $targetDirs) { - $dirPath = $dir.Path - Write-Host "" - Write-Host "Processing: $dirPath" -ForegroundColor Cyan - - try { - Push-Location -Path $dirPath - - # Check if node_modules exists, install if not - if (-not (Test-Path -Path "node_modules" -PathType Container)) { - Write-Host " Installing dependencies..." -ForegroundColor Gray - if ($DryRun) { - Write-Host " [DRY RUN] Would run: npm install" -ForegroundColor Yellow - } - else { - npm install - if ($LASTEXITCODE -ne 0) { - Write-Host " Failed to install dependencies" -ForegroundColor Red - $failureCount++ - Pop-Location - continue - } - } - } - - # Run npm audit to show vulnerabilities - Write-Host " Running npm audit..." -ForegroundColor Gray - if ($DryRun) { - Write-Host " [DRY RUN] Would run: npm audit fix" -ForegroundColor Yellow - npm audit - } - else { - npm audit fix - if ($LASTEXITCODE -ne 0) { - Write-Host " Warning: npm audit fix completed with exit code $($LASTEXITCODE)" -ForegroundColor Yellow - } - else { - Write-Host " Successfully updated vulnerable dependencies" -ForegroundColor Green - $successCount++ - } - } - - Pop-Location - } - catch { - Write-Host " Error processing directory: $_" -ForegroundColor Red - $failureCount++ - Pop-Location - } -} - -# Summary -Write-Host "" -Write-Host "================================" -ForegroundColor Cyan -Write-Host "Summary:" -ForegroundColor Cyan -Write-Host " Processed: $($targetDirs.Count)" -ForegroundColor Gray -Write-Host " Successful: $successCount" -ForegroundColor Green -Write-Host " Failed: $failureCount" -ForegroundColor $(if ($failureCount -gt 0) { "Red" } else { "Green" }) -Write-Host "================================" -ForegroundColor Cyan - -if ($DryRun) { - Write-Host "[DRY RUN] No changes were made." -ForegroundColor Yellow -} - -exit $(if ($failureCount -gt 0) { 1 } else { 0 }) diff --git a/scripts/update-vulnerable-deps.ps1 b/scripts/update-vulnerable-deps.ps1 new file mode 100644 index 000000000..477b28330 --- /dev/null +++ b/scripts/update-vulnerable-deps.ps1 @@ -0,0 +1,593 @@ +#!/usr/bin/env pwsh +<# +.SYNOPSIS +Scans the whole repository for vulnerable npm and NuGet dependencies and applies safe fixes. + +.DESCRIPTION +One command to remediate moderate-and-above security advisories across both ecosystems: + + NuGet - iterates every .csproj, restores it, runs `dotnet list package --vulnerable + --include-transitive`, dedupes advisories, SKIPS AXSharp.*/Inxton.Operon.* (those are + owned by scripts/update_axsharp_versions.ps1), resolves the minimum safe version from + the GitHub Advisory Database, and writes the bump to Directory.Packages.props + (direct = bump in place, transitive = add a new pinned ). + + npm - audits the 6 source package.json projects (installing node_modules when missing) and + runs `npm audit fix` (safe, no --force). Advisories that would need a breaking major + bump are reported as unfixed. + +A timestamped Markdown + JSON report is written to scripts/reports/. With -CreatePR the changes +are committed to branch 'fix/vulnerable-dependencies' off dev and a PR is opened against dev. + +Exit code is non-zero when vulnerabilities at/above -MinSeverity remain unfixed, so CI can gate on +it. + +.PARAMETER DryRun +Preview everything; make no file changes, no commits, no PR. (Still exits non-zero if vulns found.) + +.PARAMETER NpmOnly +Scan/fix npm only. + +.PARAMETER NuGetOnly +Scan/fix NuGet only. + +.PARAMETER CreatePR +Commit fixes to branch 'fix/vulnerable-dependencies' off origin/dev and open a PR against dev. +Cannot be combined with -DryRun. + +.PARAMETER MinSeverity +Lowest severity to act on: low | moderate | high | critical. Default: moderate. + +.PARAMETER Source +NuGet v3 feed used to look up available versions (public packages). Default nuget.org. + +.PARAMETER Token +Token for the GitHub Advisory API (avoids rate limits). Falls back to NUGET_TOKEN / +GITHUB_PACKAGES_TOKEN / GITHUB_TOKEN / GH_TOKEN. + +.PARAMETER Detailed +Verbose logging. + +.EXAMPLE +./update-vulnerable-deps.ps1 -DryRun -Detailed + +.EXAMPLE +./update-vulnerable-deps.ps1 -NuGetOnly + +.EXAMPLE +./update-vulnerable-deps.ps1 -CreatePR +#> + +[CmdletBinding()] +param( + [switch]$DryRun, + [switch]$NpmOnly, + [switch]$NuGetOnly, + [switch]$CreatePR, + [ValidateSet('low','moderate','high','critical')] + [string]$MinSeverity = 'low', + [string]$Source = 'https://api.nuget.org/v3/index.json', + [string]$Token, + [switch]$Detailed +) + +Set-StrictMode -Version Latest +$ErrorActionPreference = 'Stop' + +$scriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path +. "$scriptRoot/_deps-common.ps1" + +$repoRoot = Split-Path -Parent $scriptRoot +$propsPath = Join-Path $repoRoot 'Directory.Packages.props' + +# --------------------------------------------------------------------------- +# Validation & constants +# --------------------------------------------------------------------------- +if($DryRun -and $CreatePR){ Write-Err '-DryRun and -CreatePR cannot be combined.'; exit 1 } +if($NpmOnly -and $NuGetOnly){ Write-Err '-NpmOnly and -NuGetOnly cannot be combined.'; exit 1 } + +$doNuget = -not $NpmOnly +$doNpm = -not $NuGetOnly + +$SeverityRank = @{ low = 1; moderate = 2; high = 3; critical = 4 } +$minRank = $SeverityRank[$MinSeverity] + +# Packages owned by update_axsharp_versions.ps1 - never touched here. +$SkipPattern = '^(AXSharp|Inxton\.Operon|AXOpen)\b' + +$Token = Resolve-FeedToken -Token $Token -Detailed:$Detailed + +# Source npm projects - discovered dynamically under src/ (skips node_modules and +# bin/obj/ctrl generated copies so only first-party source manifests are audited). +$NpmProjects = @( + Get-ChildItem -Path (Join-Path $repoRoot 'src') -Recurse -File -Filter 'package.json' -ErrorAction SilentlyContinue | + Where-Object { $_.FullName -notmatch '[\\/](node_modules|bin|obj|ctrl)[\\/]' } | + ForEach-Object { $_.FullName } | + Sort-Object +) + +# Accumulators for the report. +$NuGetFixed = New-Object System.Collections.ArrayList +$NuGetSkipped = New-Object System.Collections.ArrayList +$NuGetUnfixed = New-Object System.Collections.ArrayList +$NpmResults = New-Object System.Collections.ArrayList +$ScanErrors = New-Object System.Collections.ArrayList + +# --------------------------------------------------------------------------- +# Helpers +# --------------------------------------------------------------------------- +function Test-CommandAvailable { + param([string]$Name) + $null -ne (Get-Command $Name -ErrorAction SilentlyContinue) +} + +function Get-GhsaIdFromUrl { + param([string]$Url) + if($Url -and ($Url -match '(GHSA-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{4})')){ return $Matches[1] } + return $null +} + +$script:AdvisoryCache = @{} +function Get-AdvisoryPatchedVersion { + # Queries the GitHub Advisory Database for the first patched version of $PackageId. + # Returns the patched version string, or $null when it cannot be determined. + param([string]$GhsaId,[string]$PackageId) + if(-not $GhsaId){ return $null } + if(-not $script:AdvisoryCache.ContainsKey($GhsaId)){ + $headers = @{ 'User-Agent' = 'axopen-update-vulnerable-deps'; 'Accept' = 'application/vnd.github+json' } + if($Token){ $headers['Authorization'] = "Bearer $Token" } + try { + $script:AdvisoryCache[$GhsaId] = Invoke-RestMethod -Uri "https://api.github.com/advisories/$GhsaId" -Headers $headers -TimeoutSec 30 + } catch { + if($Detailed){ Write-Warn "Advisory lookup failed for ${GhsaId}: $($_.Exception.Message)" } + $script:AdvisoryCache[$GhsaId] = $null + } + } + $adv = $script:AdvisoryCache[$GhsaId] + if(-not $adv -or -not $adv.vulnerabilities){ return $null } + foreach($v in $adv.vulnerabilities){ + if($v.package -and $v.package.ecosystem -eq 'nuget' -and $v.package.name -and ($v.package.name.ToLower() -eq $PackageId.ToLower())){ + $fpv = $v.first_patched_version + if($null -eq $fpv){ return $null } + if($fpv -is [string]){ return $fpv } + if($fpv.PSObject.Properties.Name -contains 'identifier'){ return $fpv.identifier } + } + } + return $null +} + +function Resolve-SafeNuGetVersion { + # Determines the minimum safe version for a vulnerable package: + # 1. the highest 'first patched version' across the package's advisories, then + # 2. snapped up to the lowest version actually available on the feed that is >= that patch + # and strictly greater than the current resolved version. + # Returns $null (=> report as unfixed) when no safe version can be determined. + param([string]$PackageId,[string]$CurrentVersion,[string[]]$GhsaIds,$FeedCtx) + $patched = $null + foreach($g in $GhsaIds){ + $p = Get-AdvisoryPatchedVersion -GhsaId $g -PackageId $PackageId + if($p -and (Test-VersionGreater $p $patched)){ $patched = $p } + } + if(-not $patched){ return $null } + + $available = @() + try { $available = Get-PackageVersionsFromFeed -PkgBase $FeedCtx.PkgBase -Headers $FeedCtx.Headers -PackageId $PackageId } catch { $available = @() } + if(-not $available -or $available.Count -eq 0){ + # Feed gave us nothing; trust the advisory's patched version if it improves on current. + if(Test-VersionGreater $patched $CurrentVersion){ return $patched } else { return $null } + } + + $currentIsPre = Test-IsPrerelease $CurrentVersion + $candidates = $available | + Where-Object { ($currentIsPre) -or (-not (Test-IsPrerelease $_)) } | # stable only unless current is pre + Where-Object { (Test-VersionGreater $_ $CurrentVersion) -and -not (Test-VersionGreater $patched $_) } # > current AND >= patched + + if(-not $candidates -or @($candidates).Count -eq 0){ return $null } + + # lowest such candidate = minimum safe bump + $best = @($candidates)[0] + foreach($c in $candidates){ if(Test-VersionGreater $best $c){ $best = $c } } + return $best +} + +# --------------------------------------------------------------------------- +# Directory.Packages.props editing +# --------------------------------------------------------------------------- +function Update-PropsDirect { + # Bumps an existing in place. + # Returns updated content, or $null if the package id was not found. + param([string]$Content,[string]$PackageId,[string]$NewVersion) + $idEsc = [regex]::Escape($PackageId) + # Include before Version (repo convention) + $rx1 = "(]*\bInclude=`"$idEsc`"[^>]*\bVersion=`")[^`"]*(`")" + if([regex]::IsMatch($Content,$rx1)){ + return [regex]::Replace($Content,$rx1,"`${1}$NewVersion`${2}",1) + } + # Version before Include (defensive) + $rx2 = "(]*\bVersion=`")[^`"]*(`"[^>]*\bInclude=`"$idEsc`")" + if([regex]::IsMatch($Content,$rx2)){ + return [regex]::Replace($Content,$rx2,"`${1}$NewVersion`${2}",1) + } + return $null +} + +function Test-PropsHasPackage { + param([string]$Content,[string]$PackageId) + $idEsc = [regex]::Escape($PackageId) + return [regex]::IsMatch($Content,"]*\bInclude=`"$idEsc`"") +} + +function Add-PropsTransitivePin { + # Adds a into a managed "security pins" ItemGroup, creating it before + # if absent. Returns updated content. + param([string]$Content,[string]$PackageId,[string]$NewVersion) + $marker = '' + $entry = " " + if($Content.Contains($marker)){ + # Insert as the first entry inside the existing managed ItemGroup. + $rx = [regex]::Escape($marker) + "(\r?\n\s*)" + return [regex]::Replace($Content,$rx,"`$0`r`n$entry",1) + } + $block = " $marker`r`n `r`n$entry`r`n `r`n" + return ($Content -replace '\s*$',$block) +} + +# --------------------------------------------------------------------------- +# NuGet scan & fix +# --------------------------------------------------------------------------- +function Invoke-NuGetScan { + Write-Info 'Scanning NuGet dependencies...' + if(-not (Test-CommandAvailable 'dotnet')){ Write-Err 'dotnet CLI not found on PATH.'; [void]$ScanErrors.Add('dotnet CLI not found'); return } + + $csprojFiles = Get-ChildItem -Path (Join-Path $repoRoot 'src') -Recurse -Filter '*.csproj' -ErrorAction SilentlyContinue | + Where-Object { $_.FullName -notmatch '[\\/](bin|obj)[\\/]' } + # Include the cake build project (ships in the repo). + $cakeProj = Get-ChildItem -Path (Join-Path $repoRoot 'cake') -Recurse -Filter '*.csproj' -ErrorAction SilentlyContinue | + Where-Object { $_.FullName -notmatch '[\\/](bin|obj)[\\/]' } + $csprojFiles = @($csprojFiles) + @($cakeProj) + + Write-Info "Found $($csprojFiles.Count) project(s) to scan." + + # packageId -> aggregated advisory record + $vuln = @{} + $total = $csprojFiles.Count + $i = 0 + foreach($proj in $csprojFiles){ + $i++ + $pct = if($total -gt 0){ [int](($i-1) / $total * 100) } else { 0 } + Write-Progress -Activity 'Scanning NuGet projects' ` + -Status ("[$i/$total] $($proj.Name) - $($vuln.Count) vulnerable package(s) so far") ` + -CurrentOperation 'restoring...' -PercentComplete $pct + if($Detailed){ Write-Info "[$i/$total] $($proj.FullName)" } + try { + & dotnet restore $proj.FullName --nologo *> $null + } catch { + [void]$ScanErrors.Add("restore failed: $($proj.FullName)") + if($Detailed){ Write-Warn "restore failed: $($proj.Name)" } + continue + } + Write-Progress -Activity 'Scanning NuGet projects' ` + -Status ("[$i/$total] $($proj.Name) - $($vuln.Count) vulnerable package(s) so far") ` + -CurrentOperation 'listing vulnerabilities...' -PercentComplete $pct + $raw = & dotnet list $proj.FullName package --vulnerable --include-transitive --format json 2>$null | Out-String + if(-not $raw.Trim()){ continue } + try { $parsed = $raw | ConvertFrom-Json } catch { [void]$ScanErrors.Add("unparseable output: $($proj.FullName)"); continue } + if(-not ($parsed.PSObject.Properties.Name -contains 'projects')){ continue } + foreach($p in $parsed.projects){ + if(-not ($p.PSObject.Properties.Name -contains 'frameworks') -or -not $p.frameworks){ continue } + foreach($fw in $p.frameworks){ + foreach($kind in @('topLevelPackages','transitivePackages')){ + if(-not ($fw.PSObject.Properties.Name -contains $kind) -or -not $fw.$kind){ continue } + $isDirect = ($kind -eq 'topLevelPackages') + foreach($pkg in $fw.$kind){ + if(-not ($pkg.PSObject.Properties.Name -contains 'vulnerabilities') -or -not $pkg.vulnerabilities){ continue } + $id = $pkg.id + $resolved = $pkg.resolvedVersion + foreach($adv in $pkg.vulnerabilities){ + $sev = ("$($adv.severity)").ToLower() + $rank = if($SeverityRank.ContainsKey($sev)){ $SeverityRank[$sev] } else { 0 } + if($rank -lt $minRank){ continue } + $url = if($adv.PSObject.Properties.Name -contains 'advisoryurl'){ $adv.advisoryurl } else { '' } + if(-not $vuln.ContainsKey($id)){ + $vuln[$id] = [PSCustomObject]@{ + Id=$id; Resolved=$resolved; IsDirect=$isDirect; MaxRank=$rank; + Severity=$sev; Urls=(New-Object System.Collections.ArrayList); Projects=(New-Object System.Collections.ArrayList) + } + } + $rec = $vuln[$id] + if($isDirect){ $rec.IsDirect = $true } + if($rank -gt $rec.MaxRank){ $rec.MaxRank = $rank; $rec.Severity = $sev } + if($url -and -not $rec.Urls.Contains($url)){ [void]$rec.Urls.Add($url) } + if(-not $rec.Projects.Contains($proj.Name)){ [void]$rec.Projects.Add($proj.Name) } + } + } + } + } + } + } + + Write-Progress -Activity 'Scanning NuGet projects' -Completed + + if($vuln.Count -eq 0){ Write-Info 'No NuGet vulnerabilities at/above the threshold.'; return } + Write-Info "Found $($vuln.Count) vulnerable NuGet package(s) at/above '$MinSeverity'." + + # Resolve safe versions & apply. + $feedCtx = $null + try { $feedCtx = Get-FeedContext -Feed $Source -Tok $null } catch { Write-Warn "Could not initialise NuGet feed context: $($_.Exception.Message)" } + + $content = Get-Content -LiteralPath $propsPath -Raw + $changed = $false + + foreach($id in ($vuln.Keys | Sort-Object)){ + $rec = $vuln[$id] + if($id -match $SkipPattern){ + [void]$NuGetSkipped.Add([PSCustomObject]@{ Id=$id; Current=$rec.Resolved; Severity=$rec.Severity; Reason='skipped-AXSharp (owned by update_axsharp_versions.ps1)' }) + continue + } + $ghsaIds = @($rec.Urls | ForEach-Object { Get-GhsaIdFromUrl $_ } | Where-Object { $_ }) + $safe = $null + if($feedCtx){ $safe = Resolve-SafeNuGetVersion -PackageId $id -CurrentVersion $rec.Resolved -GhsaIds $ghsaIds -FeedCtx $feedCtx } + + if(-not $safe){ + [void]$NuGetUnfixed.Add([PSCustomObject]@{ Id=$id; Current=$rec.Resolved; Severity=$rec.Severity; Direct=$rec.IsDirect; Advisories=($rec.Urls -join ' '); Reason='no safe version determined (manual review)' }) + continue + } + + $action = $null + if(Test-PropsHasPackage -Content $content -PackageId $id){ + $updated = Update-PropsDirect -Content $content -PackageId $id -NewVersion $safe + if($updated){ $content = $updated; $action = 'bumped (direct)' } + } else { + $content = Add-PropsTransitivePin -Content $content -PackageId $id -NewVersion $safe + $action = 'pinned (transitive)' + } + if($action){ + $changed = $true + [void]$NuGetFixed.Add([PSCustomObject]@{ Id=$id; From=$rec.Resolved; To=$safe; Severity=$rec.Severity; Direct=$rec.IsDirect; Action=$action; Advisories=($rec.Urls -join ' ') }) + Write-Info (" {0}: {1} -> {2} [{3}]" -f $id,$rec.Resolved,$safe,$action) + } else { + [void]$NuGetUnfixed.Add([PSCustomObject]@{ Id=$id; Current=$rec.Resolved; Severity=$rec.Severity; Direct=$rec.IsDirect; Advisories=($rec.Urls -join ' '); Reason='could not edit Directory.Packages.props' }) + } + } + + if($changed){ + if($DryRun){ + Write-Warn '[DRY RUN] Directory.Packages.props would be updated (not written).' + } else { + Write-Utf8NoBom-LF -Path $propsPath -Content $content + Write-Info 'Directory.Packages.props updated.' + } + } +} + +# --------------------------------------------------------------------------- +# npm scan & fix +# --------------------------------------------------------------------------- +function Get-NpmCountsAtOrAbove { + param($AuditObj) + $total = 0 + if($AuditObj -and $AuditObj.PSObject.Properties.Name -contains 'metadata' -and $AuditObj.metadata.PSObject.Properties.Name -contains 'vulnerabilities'){ + $v = $AuditObj.metadata.vulnerabilities + foreach($sev in @('moderate','high','critical')){ + if($SeverityRank[$sev] -ge $minRank -and ($v.PSObject.Properties.Name -contains $sev)){ $total += [int]$v.$sev } + } + if($minRank -le 1 -and ($v.PSObject.Properties.Name -contains 'low')){ $total += [int]$v.low } + } + return $total +} + +function Invoke-NpmScan { + Write-Info 'Scanning npm dependencies...' + if(-not (Test-CommandAvailable 'npm')){ Write-Err 'npm not found on PATH.'; [void]$ScanErrors.Add('npm not found'); return } + + $npmTotal = $NpmProjects.Count + $npmIdx = 0 + foreach($pkgJson in $NpmProjects){ + $npmIdx++ + if(-not (Test-Path -LiteralPath $pkgJson)){ if($Detailed){ Write-Warn "missing: $pkgJson" }; continue } + $dir = Split-Path -Parent $pkgJson + $name = (Resolve-Path -LiteralPath $dir).Path.Replace((Resolve-Path $repoRoot).Path,'').TrimStart('\','/') + Write-Progress -Activity 'Scanning npm projects' -Status "[$npmIdx/$npmTotal] $name" ` + -PercentComplete ([int](($npmIdx-1) / $npmTotal * 100)) + Write-Info " $name" + Push-Location $dir + try { + if(-not (Test-Path 'node_modules')){ + if($DryRun){ Write-Warn " [DRY RUN] would run: npm install" } + else { & npm install --no-audit --no-fund *> $null } + } + + $beforeRaw = & npm audit --json 2>$null | Out-String + $before = $null; try { $before = $beforeRaw | ConvertFrom-Json } catch {} + $beforeCount = Get-NpmCountsAtOrAbove $before + + if($beforeCount -le 0){ + [void]$NpmResults.Add([PSCustomObject]@{ Project=$name; Before=0; After=0; Fixed=0; Note='clean' }) + Pop-Location; continue + } + + if($DryRun){ + Write-Warn " [DRY RUN] would run: npm audit fix ($beforeCount vuln >= $MinSeverity)" + [void]$NpmResults.Add([PSCustomObject]@{ Project=$name; Before=$beforeCount; After=$beforeCount; Fixed=0; Note='dry-run (not fixed)' }) + Pop-Location; continue + } + + & npm audit fix *> $null + $afterRaw = & npm audit --json 2>$null | Out-String + $after = $null; try { $after = $afterRaw | ConvertFrom-Json } catch {} + $afterCount = Get-NpmCountsAtOrAbove $after + $note = if($afterCount -gt 0){ "$afterCount remain (need --force / breaking major)" } else { 'all fixed' } + [void]$NpmResults.Add([PSCustomObject]@{ Project=$name; Before=$beforeCount; After=$afterCount; Fixed=($beforeCount-$afterCount); Note=$note }) + Write-Info (" before={0} after={1} ({2})" -f $beforeCount,$afterCount,$note) + } catch { + [void]$ScanErrors.Add("npm error in ${name}: $($_.Exception.Message)") + Write-Warn " error: $($_.Exception.Message)" + } finally { + Pop-Location + } + } + Write-Progress -Activity 'Scanning npm projects' -Completed +} + +# --------------------------------------------------------------------------- +# Report +# --------------------------------------------------------------------------- +function Write-Report { + param([string]$Stamp) + $reportsDir = Join-Path $scriptRoot 'reports' + if(-not (Test-Path $reportsDir)){ New-Item -ItemType Directory -Path $reportsDir -Force | Out-Null } + $mdPath = Join-Path $reportsDir "vuln-report-$Stamp.md" + $jsonPath = Join-Path $reportsDir "vuln-report-$Stamp.json" + + $payload = [PSCustomObject]@{ + timestamp = $Stamp + minSeverity = $MinSeverity + dryRun = [bool]$DryRun + ecosystems = @{ nuget = [bool]$doNuget; npm = [bool]$doNpm } + nuget = @{ fixed = $NuGetFixed; skipped = $NuGetSkipped; unfixed = $NuGetUnfixed } + npm = $NpmResults + scanErrors = $ScanErrors + } + Write-Utf8NoBom-LF -Path $jsonPath -Content ($payload | ConvertTo-Json -Depth 8) + + $sb = New-Object System.Text.StringBuilder + [void]$sb.AppendLine("# Vulnerable dependency report") + [void]$sb.AppendLine("") + [void]$sb.AppendLine("- Generated: $Stamp") + [void]$sb.AppendLine("- Min severity: **$MinSeverity**") + [void]$sb.AppendLine("- Dry run: $([bool]$DryRun)") + [void]$sb.AppendLine("- Ecosystems: NuGet=$doNuget, npm=$doNpm") + [void]$sb.AppendLine("") + if($doNuget){ + [void]$sb.AppendLine("## NuGet") + [void]$sb.AppendLine("") + [void]$sb.AppendLine("### Fixed ($($NuGetFixed.Count))") + [void]$sb.AppendLine("| Package | From | To | Severity | Kind | Action |") + [void]$sb.AppendLine("|---|---|---|---|---|---|") + foreach($f in $NuGetFixed){ [void]$sb.AppendLine("| $($f.Id) | $($f.From) | $($f.To) | $($f.Severity) | $(if($f.Direct){'direct'}else{'transitive'}) | $($f.Action) |") } + [void]$sb.AppendLine("") + [void]$sb.AppendLine("### Unfixed - manual review ($($NuGetUnfixed.Count))") + [void]$sb.AppendLine("| Package | Current | Severity | Reason | Advisories |") + [void]$sb.AppendLine("|---|---|---|---|---|") + foreach($u in $NuGetUnfixed){ [void]$sb.AppendLine("| $($u.Id) | $($u.Current) | $($u.Severity) | $($u.Reason) | $($u.Advisories) |") } + [void]$sb.AppendLine("") + [void]$sb.AppendLine("### Skipped ($($NuGetSkipped.Count))") + foreach($s in $NuGetSkipped){ [void]$sb.AppendLine("- $($s.Id) ($($s.Current), $($s.Severity)) - $($s.Reason)") } + [void]$sb.AppendLine("") + } + if($doNpm){ + [void]$sb.AppendLine("## npm") + [void]$sb.AppendLine("") + [void]$sb.AppendLine("| Project | Before | After | Fixed | Note |") + [void]$sb.AppendLine("|---|---|---|---|---|") + foreach($n in $NpmResults){ [void]$sb.AppendLine("| $($n.Project) | $($n.Before) | $($n.After) | $($n.Fixed) | $($n.Note) |") } + [void]$sb.AppendLine("") + } + if($ScanErrors.Count -gt 0){ + [void]$sb.AppendLine("## Scan errors") + foreach($e in $ScanErrors){ [void]$sb.AppendLine("- $e") } + } + Write-Utf8NoBom-LF -Path $mdPath -Content $sb.ToString() + + Write-Info "Report: $mdPath" + return $mdPath +} + +# --------------------------------------------------------------------------- +# Commit + PR +# --------------------------------------------------------------------------- +function Invoke-CreatePR { + param([string]$ReportPath) + if(-not (Test-CommandAvailable 'git')){ Write-Err 'git not found; cannot create PR.'; return } + if(-not (Test-CommandAvailable 'gh')){ Write-Err 'gh CLI not found; cannot open PR.'; return } + + $branch = 'fix/vulnerable-dependencies' + Write-Info "Creating branch '$branch' off origin/dev and opening PR..." + + & git -C $repoRoot fetch origin dev --quiet + # Carry working-tree fixes onto a fresh branch from origin/dev. + & git -C $repoRoot stash push -u -m 'vuln-fix-wip' *> $null + $stashed = ($LASTEXITCODE -eq 0) + & git -C $repoRoot switch -C $branch origin/dev + if($LASTEXITCODE -ne 0){ Write-Err "Failed to create branch $branch."; if($stashed){ & git -C $repoRoot stash pop *> $null }; return } + if($stashed){ + & git -C $repoRoot stash pop + if($LASTEXITCODE -ne 0){ Write-Err 'Stash pop conflicted; resolve manually. Aborting PR.'; return } + } + + & git -C $repoRoot add -- 'Directory.Packages.props' '**/package.json' '**/package-lock.json' + & git -C $repoRoot commit -m @' +fix(deps): remediate moderate+ npm & NuGet vulnerabilities + +Automated by scripts/update-vulnerable-deps.ps1. + +Co-Authored-By: Claude Opus 4.8 (1M context) +'@ + if($LASTEXITCODE -ne 0){ Write-Warn 'Nothing to commit (no changes staged). Skipping PR.'; return } + + & git -C $repoRoot push -u origin $branch + if($LASTEXITCODE -ne 0){ Write-Err 'git push failed.'; return } + + $fixedLines = ($NuGetFixed | ForEach-Object { "- NuGet $($_.Id): $($_.From) -> $($_.To) ($($_.Severity))" }) -join "`n" + $npmLines = ($NpmResults | Where-Object { $_.Fixed -gt 0 } | ForEach-Object { "- npm $($_.Project): fixed $($_.Fixed)" }) -join "`n" + $unfixed = ($NuGetUnfixed | ForEach-Object { "- $($_.Id) ($($_.Severity)): $($_.Reason)" }) -join "`n" + $body = @" +Automated remediation of moderate-and-above npm & NuGet vulnerabilities. + +## Fixed +$fixedLines +$npmLines + +## Needs manual review +$unfixed + +See the attached report ($([System.IO.Path]::GetFileName($ReportPath))) for full detail. + +🤖 Generated with [Claude Code](https://claude.com/claude-code) +"@ + & gh pr create --base dev --head $branch --title 'fix(deps): remediate moderate+ npm & NuGet vulnerabilities' --body $body + if($LASTEXITCODE -ne 0){ Write-Err 'gh pr create failed.' } else { Write-Info 'PR opened against dev.' } +} + +# --------------------------------------------------------------------------- +# Main +# --------------------------------------------------------------------------- +$stamp = (Get-Date).ToString('yyyy-MM-dd-HHmmss') +Write-Info "update-vulnerable-deps (minSeverity=$MinSeverity, dryRun=$DryRun, npm=$doNpm, nuget=$doNuget)" + +if($doNuget){ Invoke-NuGetScan } +if($doNpm){ Invoke-NpmScan } + +$reportPath = Write-Report -Stamp $stamp + +# Determine unfixed count for exit code. +$npmRemaining = ($NpmResults | Measure-Object -Property After -Sum).Sum +if($null -eq $npmRemaining){ $npmRemaining = 0 } +$unfixedCount = $NuGetUnfixed.Count + [int]$npmRemaining + +Write-Host '' +Write-Host '================ SUMMARY ================' -ForegroundColor Cyan +Write-Host (" NuGet fixed : {0}" -f $NuGetFixed.Count) +Write-Host (" NuGet skipped : {0}" -f $NuGetSkipped.Count) +Write-Host (" NuGet unfixed : {0}" -f $NuGetUnfixed.Count) +Write-Host (" npm projects : {0}" -f $NpmResults.Count) +Write-Host (" npm remaining : {0}" -f $npmRemaining) +Write-Host (" scan errors : {0}" -f $ScanErrors.Count) +Write-Host '========================================' -ForegroundColor Cyan + +if($CreatePR -and -not $DryRun){ + if($NuGetFixed.Count -gt 0 -or ($NpmResults | Where-Object { $_.Fixed -gt 0 })){ + Invoke-CreatePR -ReportPath $reportPath + } else { + Write-Warn 'No fixes applied; skipping PR creation.' + } +} + +if($ScanErrors.Count -gt 0){ Write-Warn "$($ScanErrors.Count) scan error(s) - see report." } + +if($unfixedCount -gt 0){ + Write-Warn "$unfixedCount vulnerability/vulnerabilities remain unfixed." + exit 1 +} +Write-Info 'No outstanding vulnerabilities at/above threshold.' +exit 0 diff --git a/scripts/update_axsharp_versions.ps1 b/scripts/update_axsharp_versions.ps1 index 839983692..7082969da 100644 --- a/scripts/update_axsharp_versions.ps1 +++ b/scripts/update_axsharp_versions.ps1 @@ -8,7 +8,11 @@ 3. Updates versions for: - .config/dotnet-tools.json (all tools whose name starts with AXSharp. or Inxton.Operon.) - src/Directory.Packages.props (all and Include="Inxton.Operon.*" ... /> entries) - 4. Supports -DryRun to preview changes and -Verbose for detailed logging. + 4. Reconciles AXSharp's transitive (third-party) dependencies: reads each AXSharp.* package's + .nuspec at the resolved version, and bumps any already-pinned entry up to the + version AXSharp requires (bump-up only; never downgrades, never adds new entries). Useful with + CentralPackageTransitivePinningEnabled. Disable with -SkipTransitive. + 5. Supports -DryRun to preview changes and -Verbose for detailed logging. .PARAMETER AxSharpVersion Explicit version to set for AXSharp.* packages instead of auto-detecting the latest from NuGet. @@ -39,7 +43,8 @@ param( [string]$Username, # Optional for private feed auth (GitHub Packages). If omitted and Token supplied, 'USERNAME' placeholder is used. [string]$Token, # Personal Access Token or NuGet API key for private feed (PAT needs packaging:read scope) [switch]$NormalizeJson, # When set, rewrites dotnet-tools.json with standard compact formatting instead of preserving existing indentation - [switch]$ListAvailable # If set, lists available versions (after auth) and exits (unless versions also supplied) + [switch]$ListAvailable, # If set, lists available versions (after auth) and exits (unless versions also supplied) + [switch]$SkipTransitive # If set, does not reconcile AXSharp's transitive (third-party) dependencies in Directory.Packages.props ) Set-StrictMode -Version Latest @@ -181,6 +186,107 @@ function Get-LatestVersion { } } +function Get-FeedContext { + # Resolves the service index once and returns the PackageBaseAddress + auth headers + # for reuse across multiple package requests (versions, nuspec, ...). + param([string]$Feed,[string]$User,[string]$Tok) + $serviceIndexUrl = if($Feed.ToLower().EndsWith('index.json')) { $Feed } else { ($Feed.TrimEnd('/')) + '/index.json' } + $headers = @{} + if($Tok){ + $u = if($User){$User}else{'USERNAME'} + $basic = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $u,$Tok))) + $headers['Authorization'] = "Basic $basic" + } + $si = Invoke-RestMethod -Uri $serviceIndexUrl -Headers $headers -TimeoutSec 30 + if(-not $si.resources){ throw "Service index missing resources at $serviceIndexUrl" } + $pkgBase = ($si.resources | Where-Object { $_.'@type' -eq 'PackageBaseAddress/3.0.0' } | Select-Object -First 1).'@id' + if(-not $pkgBase){ throw 'PackageBaseAddress/3.0.0 resource not found in service index.' } + if($pkgBase[-1] -ne '/') { $pkgBase += '/' } + [PSCustomObject]@{ PkgBase=$pkgBase; Headers=$headers } +} + +function Get-NuspecXml { + # Returns the .nuspec of a package@version as an [xml]. Tries the flat-container .nuspec + # endpoint first (served by nuget.org); on 404 (GitHub Packages does not expose it) falls + # back to downloading the .nupkg and extracting the .nuspec entry from the zip. + param([string]$PkgBase,[hashtable]$Headers,[string]$PackageId,[string]$Version) + $lowerId = $PackageId.ToLower() + + $nuspecUrl = "$PkgBase$lowerId/$Version/$lowerId.nuspec" + try { + $resp = Invoke-WebRequest -Uri $nuspecUrl -Headers $Headers -TimeoutSec 30 -UseBasicParsing + return [xml]$resp.Content + } catch { + $code = $null + if($_.Exception.Response){ $code = [int]$_.Exception.Response.StatusCode } + if($code -and $code -ne 404){ throw "Failed to fetch nuspec ($nuspecUrl): $($_.Exception.Message)" } + # 404 -> feed does not serve standalone .nuspec; fall back to the .nupkg below. + } + + $nupkgUrl = "$PkgBase$lowerId/$Version/$lowerId.$Version.nupkg" + $tmpPkg = [System.IO.Path]::GetTempFileName() + '.nupkg' + try { + Invoke-WebRequest -Uri $nupkgUrl -Headers $Headers -TimeoutSec 60 -UseBasicParsing -OutFile $tmpPkg + Add-Type -AssemblyName System.IO.Compression.FileSystem -ErrorAction SilentlyContinue + $zip = [System.IO.Compression.ZipFile]::OpenRead($tmpPkg) + try { + $entry = $zip.Entries | Where-Object { $_.FullName.ToLower().EndsWith('.nuspec') } | Select-Object -First 1 + if(-not $entry){ throw "No .nuspec entry inside $nupkgUrl" } + $sr = New-Object System.IO.StreamReader($entry.Open()) + try { $content = $sr.ReadToEnd() } finally { $sr.Dispose() } + } finally { + $zip.Dispose() + } + return [xml]$content + } catch { + throw "Failed to read package metadata for ${PackageId}@${Version} (tried nuspec + nupkg): $($_.Exception.Message)" + } finally { + Remove-Item -LiteralPath $tmpPkg -ErrorAction SilentlyContinue + } +} + +function Get-PackageDependencies { + # Reads a package's .nuspec at a specific version and returns its declared dependencies + # as a flat list of [PSCustomObject]@{ Id; Version }, across all target frameworks. + param([string]$PkgBase,[hashtable]$Headers,[string]$PackageId,[string]$Version) + $doc = Get-NuspecXml -PkgBase $PkgBase -Headers $Headers -PackageId $PackageId -Version $Version + $nsUri = $doc.DocumentElement.NamespaceURI + if($nsUri){ + $nsm = New-Object System.Xml.XmlNamespaceManager($doc.NameTable) + $nsm.AddNamespace('n',$nsUri) + $nodes = $doc.SelectNodes('//n:dependency',$nsm) + } else { + $nodes = $doc.SelectNodes('//dependency') + } + $deps = @() + foreach($n in $nodes){ + $id = $n.GetAttribute('id') + $ver = $n.GetAttribute('version') + if($id){ $deps += [PSCustomObject]@{ Id=$id; Version=$ver } } + } + return $deps +} + +function Get-VersionLowerBound { + # Extracts the lower-bound version from a NuGet dependency version string. + # Handles plain ("1.2.3"), exact ("[1.2.3]") and range ("[1.2.3, )", "(1.0,2.0)") forms. + # Returns $null when no usable lower bound exists (e.g. "(,2.0)"). + param([string]$Range) + if([string]::IsNullOrWhiteSpace($Range)){ return $null } + $r = $Range.Trim().Trim('[',']','(',')',' ') + $r = $r.Split(',')[0].Trim() + if([string]::IsNullOrWhiteSpace($r)){ return $null } + return $r +} + +function Test-VersionGreater { + # Returns $true when semver-ish version $A is strictly greater than $B. + param([string]$A,[string]$B) + if([string]::IsNullOrWhiteSpace($B)){ return $true } + if([string]::IsNullOrWhiteSpace($A)){ return $false } + return ( (Compare-VersionRecord (ConvertTo-VersionRecord $A) (ConvertTo-VersionRecord $B)) -gt 0 ) +} + # Query for AXSharp version if(-not $AxSharpVersion){ Write-Info "Discovering latest AXSharp.ixc version from source: $Source ..." @@ -340,12 +446,70 @@ $propsUpdated = [System.Text.RegularExpressions.Regex]::Replace($propsUpdated, $ } }) +### Reconcile AXSharp transitive (third-party) dependencies +# Read each AXSharp.* package's .nuspec at the resolved version, then bump any already-pinned +# entry up to the version AXSharp requires. Bump-up only: never downgrades a +# deliberately-pinned newer version, and never adds entries that aren't already listed. +if(-not $SkipTransitive){ + Write-Info 'Reconciling AXSharp transitive dependencies...' + $axPkgIds = [regex]::Matches($propsRaw,')' + $propsUpdated = [System.Text.RegularExpressions.Regex]::Replace($propsUpdated, $pattern, { + param($m) + $old = $m.Groups[2].Value + if(Test-VersionGreater $newVer $old){ + $script:changes += "Directory.Packages.props (transitive): $depId $old -> $newVer" + return $m.Groups[1].Value + $newVer + $m.Groups[3].Value + } else { + if($Detailed -and $old -ne $newVer){ Write-Info "Transitive $depId left at $old (AXSharp requires >= $newVer; pinned version is newer)" } + return $m.Value + } + }) + } + } +} + if(-not $DryRun){ if($propsUpdated -ne $propsRaw){ #Set-Content -Path $propsPath -Value $propsUpdated -Encoding UTF8 Write-Utf8NoBom-LF -Path $propsPath -Content $propsUpdated } elseif($Detailed){ - Write-Info 'No AXSharp.* or Inxton.Operon.* entries needed updating in Directory.Packages.props.' + Write-Info 'No AXSharp.*, Inxton.Operon.* or transitive entries needed updating in Directory.Packages.props.' } } diff --git a/src/ax.axopen.app/ctrl/apax.yml b/src/ax.axopen.app/ctrl/apax.yml index c222e84a2..948050959 100644 --- a/src/ax.axopen.app/ctrl/apax.yml +++ b/src/ax.axopen.app/ctrl/apax.yml @@ -6,7 +6,7 @@ files: registries: "@inxton": "https://npm.pkg.github.com/" catalogs: - "@inxton/ax.catalog": '0.0.51' + "@inxton/ax.catalog": '0.0.52' devDependencies: "@inxton/ax-sdk": '0.0.0-dev.0' dependencies: @@ -14,8 +14,8 @@ dependencies: "@ax/system-bitaccess": 10.4.16 "@ax/system-math": 10.4.16 "@ax/system-serde": 10.4.16 - "@ax/dcp-utility": 1.2.0 - "@ax/hardware-diagnostics": 1.1.1 + "@ax/dcp-utility": 1.2.1 + "@ax/hardware-diagnostics": 1.2.0 "@ax/simatic-tasks": 11.0.2 installStrategy: strict apaxVersion: 3.5.0 diff --git a/src/ax.axopen.hwlibrary/ctrl/apax.yml b/src/ax.axopen.hwlibrary/ctrl/apax.yml index 17d822ac4..5e3b2a176 100644 --- a/src/ax.axopen.hwlibrary/ctrl/apax.yml +++ b/src/ax.axopen.hwlibrary/ctrl/apax.yml @@ -6,7 +6,7 @@ files: registries: "@inxton": "https://npm.pkg.github.com/" catalogs: - "@inxton/ax.catalog": '0.0.51' + "@inxton/ax.catalog": '0.0.52' devDependencies: "@inxton/ax-sdk": '0.0.0-dev.0' dependencies: diff --git a/src/ax.axopen.min/ctrl/apax.yml b/src/ax.axopen.min/ctrl/apax.yml index 7d48cec69..1fd659fd6 100644 --- a/src/ax.axopen.min/ctrl/apax.yml +++ b/src/ax.axopen.min/ctrl/apax.yml @@ -6,7 +6,7 @@ files: registries: "@inxton": "https://npm.pkg.github.com/" catalogs: - "@inxton/ax.catalog": '0.0.51' + "@inxton/ax.catalog": '0.0.52' devDependencies: "@inxton/ax-sdk": '0.0.0-dev.0' dependencies: diff --git a/src/ax.catalog/apax.yml b/src/ax.catalog/apax.yml index 5da316ada..5d03afb50 100644 --- a/src/ax.catalog/apax.yml +++ b/src/ax.catalog/apax.yml @@ -1,5 +1,5 @@ name: "@inxton/ax.catalog" -version: '0.0.51' +version: '0.0.52' registries: "@inxton": "https://npm.pkg.github.com/" type: catalog @@ -12,21 +12,21 @@ catalogDependencies: "@ax/axunitst": 9.4.8 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 9.4.8 "@ax/axunitst-library": 9.4.8 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 9.4.8 "@ax/build-native": 16.1.51 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 16.1.51 - "@ax/certificate-management": 2.0.0 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 2.0.0 - "@ax/dcp-utility": 1.2.0 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 1.2.0 + "@ax/certificate-management": 2.0.1 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 2.0.0 + "@ax/dcp-utility": 1.2.1 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 1.2.0 "@ax/debug-st-ls-plugin": 1.0.10 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 1.0.10 - "@ax/diagnostic-buffer": 2.1.1 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 2.1.1 - "@ax/hardware-diagnostics": 1.1.1 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 1.1.1 + "@ax/diagnostic-buffer": 2.2.0 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 2.1.1 + "@ax/hardware-diagnostics": 1.2.0 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 1.1.1 "@ax/hw-et200sp": 4.4.1 # @ax/simatic-ax@2510.12.0 contained at the time of creation this catalog (25.5.2026) version 4.4.1 "@ax/hw-s7-1500": 4.4.1 # @ax/simatic-ax@2510.12.0 contained at the time of creation this catalog (25.5.2026) version 4.4.1 "@ax/hwc": 4.4.1 # @ax/simatic-ax@2510.12.0 contained at the time of creation this catalog (25.5.2026) version 4.4.1 - "@ax/hwld": 3.4.0 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 3.4.0 - "@ax/mod": 1.13.21 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 1.13.21 - "@ax/mon": 1.13.21 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 1.13.21 - "@ax/plc-control": 1.6.3 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 1.6.3 - "@ax/plc-info": 4.1.1 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 4.1.1 + "@ax/hwld": 3.5.0 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 3.4.0 + "@ax/mod": 1.14.13 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 1.13.21 + "@ax/mon": 1.14.13 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 1.13.21 + "@ax/plc-control": 1.7.22 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 1.6.3 + "@ax/plc-info": 4.2.0 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 4.1.1 "@ax/plc-web-app-manager": 1.2.0 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 1.2.0 - "@ax/sdb": 1.13.21 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 1.13.21 + "@ax/sdb": 1.14.13 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 1.13.21 "@ax/sdk": 2510.12.0 # @ax/simatic-ax@2510.12.0 contained at the time of creation this catalog (25.5.2026) version 2510.12.0 "@ax/simatic-alarming": 5.1.0 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 5.1.0 "@ax/simatic-clocks": 11.0.116 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 11.0.116 @@ -58,12 +58,12 @@ catalogDependencies: "@ax/simatic-pointtopoint": 4.0.54 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 4.0.54 "@ax/simatic-tasks": 11.0.2 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 11.0.2 "@ax/simatic-technology-objects": 4.0.43 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 4.0.43 - "@ax/sld": 3.6.3 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 3.6.3 - "@ax/st-lang-contrib-xlad": 1.0.0 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 1.0.0 - "@ax/st-ls": 11.4.57 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 11.4.57 + "@ax/sld": 3.8.3 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 3.6.3 + "@ax/st-lang-contrib-xlad": 1.1.0 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 1.0.0 + "@ax/st-ls": 11.5.53 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 11.4.57 "@ax/st-opcua.stc-plugin": 2.0.0 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 2.0.0 "@ax/st-resources.stc-plugin": 4.0.3 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 4.0.3 - "@ax/stc": 11.4.57 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 11.4.57 + "@ax/stc": 11.5.53 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 11.4.57 "@ax/system": 10.4.16 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 10.4.16 "@ax/system-bistable": 10.4.16 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 10.4.16 "@ax/system-bitaccess": 10.4.16 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 10.4.16 @@ -78,8 +78,8 @@ catalogDependencies: "@ax/system-serde": 10.4.16 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 10.4.16 "@ax/system-strings": 10.4.16 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 10.4.16 "@ax/system-timer": 10.4.16 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 10.4.16 - "@ax/target-llvm": 11.4.57 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 11.4.57 - "@ax/target-mc7plus": 11.4.57 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 11.4.57 + "@ax/target-llvm": 11.5.53 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 11.4.57 + "@ax/target-mc7plus": 11.5.53 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 11.4.57 "@ax/tia2st": 4.3.5 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 4.3.5 - "@ax/trace": 3.3.1 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 3.3.1 + "@ax/trace": 3.4.0 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 3.3.1 "@ax/xlad-service": 1.1.0 # @ax/simatic-ax@2510.12.0 contained at the time of creation this catalog (25.5.2026) version 1.1.0 diff --git a/src/components.abb.robotics/package-lock.json b/src/components.abb.robotics/package-lock.json deleted file mode 100644 index 13ea2dbbc..000000000 --- a/src/components.abb.robotics/package-lock.json +++ /dev/null @@ -1,1174 +0,0 @@ -{ - "name": "components.abb.robotics", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "dependencies": { - "@tailwindcss/cli": "^4.1.11", - "tailwindcss": "^4.1.11" - } - }, - "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/@isaacs/fs-minipass": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", - "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", - "license": "ISC", - "dependencies": { - "minipass": "^7.0.4" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.12", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz", - "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==", - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "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/sourcemap-codec": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz", - "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==", - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.29", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz", - "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==", - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@parcel/watcher": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", - "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==", - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "detect-libc": "^1.0.3", - "is-glob": "^4.0.3", - "micromatch": "^4.0.5", - "node-addon-api": "^7.0.0" - }, - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "optionalDependencies": { - "@parcel/watcher-android-arm64": "2.5.1", - "@parcel/watcher-darwin-arm64": "2.5.1", - "@parcel/watcher-darwin-x64": "2.5.1", - "@parcel/watcher-freebsd-x64": "2.5.1", - "@parcel/watcher-linux-arm-glibc": "2.5.1", - "@parcel/watcher-linux-arm-musl": "2.5.1", - "@parcel/watcher-linux-arm64-glibc": "2.5.1", - "@parcel/watcher-linux-arm64-musl": "2.5.1", - "@parcel/watcher-linux-x64-glibc": "2.5.1", - "@parcel/watcher-linux-x64-musl": "2.5.1", - "@parcel/watcher-win32-arm64": "2.5.1", - "@parcel/watcher-win32-ia32": "2.5.1", - "@parcel/watcher-win32-x64": "2.5.1" - } - }, - "node_modules/@parcel/watcher-android-arm64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", - "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-darwin-arm64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz", - "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-darwin-x64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", - "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-freebsd-x64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", - "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm-glibc": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", - "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm-musl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", - "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm64-glibc": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz", - "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm64-musl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz", - "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-x64-glibc": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz", - "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-x64-musl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz", - "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-win32-arm64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz", - "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-win32-ia32": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz", - "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-win32-x64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz", - "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@tailwindcss/cli": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/cli/-/cli-4.1.11.tgz", - "integrity": "sha512-7RAFOrVaXCFz5ooEG36Kbh+sMJiI2j4+Ozp71smgjnLfBRu7DTfoq8DsTvzse2/6nDeo2M3vS/FGaxfDgr3rtQ==", - "license": "MIT", - "dependencies": { - "@parcel/watcher": "^2.5.1", - "@tailwindcss/node": "4.1.11", - "@tailwindcss/oxide": "4.1.11", - "enhanced-resolve": "^5.18.1", - "mri": "^1.2.0", - "picocolors": "^1.1.1", - "tailwindcss": "4.1.11" - }, - "bin": { - "tailwindcss": "dist/index.mjs" - } - }, - "node_modules/@tailwindcss/node": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.11.tgz", - "integrity": "sha512-yzhzuGRmv5QyU9qLNg4GTlYI6STedBWRE7NjxP45CsFYYq9taI0zJXZBMqIC/c8fViNLhmrbpSFS57EoxUmD6Q==", - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.3.0", - "enhanced-resolve": "^5.18.1", - "jiti": "^2.4.2", - "lightningcss": "1.30.1", - "magic-string": "^0.30.17", - "source-map-js": "^1.2.1", - "tailwindcss": "4.1.11" - } - }, - "node_modules/@tailwindcss/oxide": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.11.tgz", - "integrity": "sha512-Q69XzrtAhuyfHo+5/HMgr1lAiPP/G40OMFAnws7xcFEYqcypZmdW8eGXaOUIeOl1dzPJBPENXgbjsOyhg2nkrg==", - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "detect-libc": "^2.0.4", - "tar": "^7.4.3" - }, - "engines": { - "node": ">= 10" - }, - "optionalDependencies": { - "@tailwindcss/oxide-android-arm64": "4.1.11", - "@tailwindcss/oxide-darwin-arm64": "4.1.11", - "@tailwindcss/oxide-darwin-x64": "4.1.11", - "@tailwindcss/oxide-freebsd-x64": "4.1.11", - "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.11", - "@tailwindcss/oxide-linux-arm64-gnu": "4.1.11", - "@tailwindcss/oxide-linux-arm64-musl": "4.1.11", - "@tailwindcss/oxide-linux-x64-gnu": "4.1.11", - "@tailwindcss/oxide-linux-x64-musl": "4.1.11", - "@tailwindcss/oxide-wasm32-wasi": "4.1.11", - "@tailwindcss/oxide-win32-arm64-msvc": "4.1.11", - "@tailwindcss/oxide-win32-x64-msvc": "4.1.11" - } - }, - "node_modules/@tailwindcss/oxide-android-arm64": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.11.tgz", - "integrity": "sha512-3IfFuATVRUMZZprEIx9OGDjG3Ou3jG4xQzNTvjDoKmU9JdmoCohQJ83MYd0GPnQIu89YoJqvMM0G3uqLRFtetg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-darwin-arm64": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.11.tgz", - "integrity": "sha512-ESgStEOEsyg8J5YcMb1xl8WFOXfeBmrhAwGsFxxB2CxY9evy63+AtpbDLAyRkJnxLy2WsD1qF13E97uQyP1lfQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-darwin-x64": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.11.tgz", - "integrity": "sha512-EgnK8kRchgmgzG6jE10UQNaH9Mwi2n+yw1jWmof9Vyg2lpKNX2ioe7CJdf9M5f8V9uaQxInenZkOxnTVL3fhAw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-freebsd-x64": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.11.tgz", - "integrity": "sha512-xdqKtbpHs7pQhIKmqVpxStnY1skuNh4CtbcyOHeX1YBE0hArj2romsFGb6yUmzkq/6M24nkxDqU8GYrKrz+UcA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.11.tgz", - "integrity": "sha512-ryHQK2eyDYYMwB5wZL46uoxz2zzDZsFBwfjssgB7pzytAeCCa6glsiJGjhTEddq/4OsIjsLNMAiMlHNYnkEEeg==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.11.tgz", - "integrity": "sha512-mYwqheq4BXF83j/w75ewkPJmPZIqqP1nhoghS9D57CLjsh3Nfq0m4ftTotRYtGnZd3eCztgbSPJ9QhfC91gDZQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm64-musl": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.11.tgz", - "integrity": "sha512-m/NVRFNGlEHJrNVk3O6I9ggVuNjXHIPoD6bqay/pubtYC9QIdAMpS+cswZQPBLvVvEF6GtSNONbDkZrjWZXYNQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-x64-gnu": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.11.tgz", - "integrity": "sha512-YW6sblI7xukSD2TdbbaeQVDysIm/UPJtObHJHKxDEcW2exAtY47j52f8jZXkqE1krdnkhCMGqP3dbniu1Te2Fg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-x64-musl": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.11.tgz", - "integrity": "sha512-e3C/RRhGunWYNC3aSF7exsQkdXzQ/M+aYuZHKnw4U7KQwTJotnWsGOIVih0s2qQzmEzOFIJ3+xt7iq67K/p56Q==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.11.tgz", - "integrity": "sha512-Xo1+/GU0JEN/C/dvcammKHzeM6NqKovG+6921MR6oadee5XPBaKOumrJCXvopJ/Qb5TH7LX/UAywbqrP4lax0g==", - "bundleDependencies": [ - "@napi-rs/wasm-runtime", - "@emnapi/core", - "@emnapi/runtime", - "@tybys/wasm-util", - "@emnapi/wasi-threads", - "tslib" - ], - "cpu": [ - "wasm32" - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "^1.4.3", - "@emnapi/runtime": "^1.4.3", - "@emnapi/wasi-threads": "^1.0.2", - "@napi-rs/wasm-runtime": "^0.2.11", - "@tybys/wasm-util": "^0.9.0", - "tslib": "^2.8.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core": { - "version": "1.4.3", - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/wasi-threads": "1.0.2", - "tslib": "^2.4.0" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime": { - "version": "1.4.3", - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads": { - "version": "1.0.2", - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": { - "version": "0.2.11", - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "^1.4.3", - "@emnapi/runtime": "^1.4.3", - "@tybys/wasm-util": "^0.9.0" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": { - "version": "0.9.0", - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib": { - "version": "2.8.0", - "inBundle": true, - "license": "0BSD", - "optional": true - }, - "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.11.tgz", - "integrity": "sha512-UgKYx5PwEKrac3GPNPf6HVMNhUIGuUh4wlDFR2jYYdkX6pL/rn73zTq/4pzUm8fOjAn5L8zDeHp9iXmUGOXZ+w==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-win32-x64-msvc": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.11.tgz", - "integrity": "sha512-YfHoggn1j0LK7wR82TOucWc5LDCguHnoS879idHekmmiR7g9HUtMw9MI0NHatS28u/Xlkfi9w5RJWgz2Dl+5Qg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide/node_modules/detect-libc": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", - "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", - "license": "Apache-2.0", - "engines": { - "node": ">=8" - } - }, - "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/chownr": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", - "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, - "node_modules/detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", - "license": "Apache-2.0", - "bin": { - "detect-libc": "bin/detect-libc.js" - }, - "engines": { - "node": ">=0.10" - } - }, - "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/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/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/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-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-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/jiti": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", - "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", - "license": "MIT", - "bin": { - "jiti": "lib/jiti-cli.mjs" - } - }, - "node_modules/lightningcss": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz", - "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==", - "license": "MPL-2.0", - "dependencies": { - "detect-libc": "^2.0.3" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "optionalDependencies": { - "lightningcss-darwin-arm64": "1.30.1", - "lightningcss-darwin-x64": "1.30.1", - "lightningcss-freebsd-x64": "1.30.1", - "lightningcss-linux-arm-gnueabihf": "1.30.1", - "lightningcss-linux-arm64-gnu": "1.30.1", - "lightningcss-linux-arm64-musl": "1.30.1", - "lightningcss-linux-x64-gnu": "1.30.1", - "lightningcss-linux-x64-musl": "1.30.1", - "lightningcss-win32-arm64-msvc": "1.30.1", - "lightningcss-win32-x64-msvc": "1.30.1" - } - }, - "node_modules/lightningcss-darwin-arm64": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz", - "integrity": "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-darwin-x64": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz", - "integrity": "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-freebsd-x64": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz", - "integrity": "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz", - "integrity": "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==", - "cpu": [ - "arm" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz", - "integrity": "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz", - "integrity": "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz", - "integrity": "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-musl": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz", - "integrity": "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz", - "integrity": "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz", - "integrity": "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss/node_modules/detect-libc": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", - "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", - "license": "Apache-2.0", - "engines": { - "node": ">=8" - } - }, - "node_modules/magic-string": { - "version": "0.30.17", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", - "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0" - } - }, - "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/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/minizlib": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", - "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", - "license": "MIT", - "dependencies": { - "minipass": "^7.1.2" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/mri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", - "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/node-addon-api": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", - "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", - "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/picomatch": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", - "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "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/tailwindcss": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.11.tgz", - "integrity": "sha512-2E9TBm6MDD/xKYe+dvJZAmg3yxIEDNRc0jwlNyDg/4Fil2QcSLjFKGVff0lAf1jjeaArlG/M75Ey/EYr/OJtBA==", - "license": "MIT" - }, - "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/tar": { - "version": "7.5.13", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.13.tgz", - "integrity": "sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng==", - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/fs-minipass": "^4.0.0", - "chownr": "^3.0.0", - "minipass": "^7.1.2", - "minizlib": "^3.1.0", - "yallist": "^5.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "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/yallist": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", - "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - } - } -} diff --git a/src/components.abb.robotics/package.json b/src/components.abb.robotics/package.json deleted file mode 100644 index 59aeb296f..000000000 --- a/src/components.abb.robotics/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "dependencies": { - "@tailwindcss/cli": "^4.1.11", - "tailwindcss": "^4.1.11" - } -} diff --git a/src/components.abstractions/package-lock.json b/src/components.abstractions/package-lock.json deleted file mode 100644 index c180f8e4c..000000000 --- a/src/components.abstractions/package-lock.json +++ /dev/null @@ -1,1174 +0,0 @@ -{ - "name": "components.abstractions", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "dependencies": { - "@tailwindcss/cli": "^4.1.11", - "tailwindcss": "^4.1.11" - } - }, - "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/@isaacs/fs-minipass": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", - "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", - "license": "ISC", - "dependencies": { - "minipass": "^7.0.4" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.12", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz", - "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==", - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "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/sourcemap-codec": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz", - "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==", - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.29", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz", - "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==", - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@parcel/watcher": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", - "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==", - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "detect-libc": "^1.0.3", - "is-glob": "^4.0.3", - "micromatch": "^4.0.5", - "node-addon-api": "^7.0.0" - }, - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "optionalDependencies": { - "@parcel/watcher-android-arm64": "2.5.1", - "@parcel/watcher-darwin-arm64": "2.5.1", - "@parcel/watcher-darwin-x64": "2.5.1", - "@parcel/watcher-freebsd-x64": "2.5.1", - "@parcel/watcher-linux-arm-glibc": "2.5.1", - "@parcel/watcher-linux-arm-musl": "2.5.1", - "@parcel/watcher-linux-arm64-glibc": "2.5.1", - "@parcel/watcher-linux-arm64-musl": "2.5.1", - "@parcel/watcher-linux-x64-glibc": "2.5.1", - "@parcel/watcher-linux-x64-musl": "2.5.1", - "@parcel/watcher-win32-arm64": "2.5.1", - "@parcel/watcher-win32-ia32": "2.5.1", - "@parcel/watcher-win32-x64": "2.5.1" - } - }, - "node_modules/@parcel/watcher-android-arm64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", - "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-darwin-arm64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz", - "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-darwin-x64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", - "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-freebsd-x64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", - "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm-glibc": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", - "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm-musl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", - "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm64-glibc": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz", - "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm64-musl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz", - "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-x64-glibc": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz", - "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-x64-musl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz", - "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-win32-arm64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz", - "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-win32-ia32": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz", - "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-win32-x64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz", - "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@tailwindcss/cli": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/cli/-/cli-4.1.11.tgz", - "integrity": "sha512-7RAFOrVaXCFz5ooEG36Kbh+sMJiI2j4+Ozp71smgjnLfBRu7DTfoq8DsTvzse2/6nDeo2M3vS/FGaxfDgr3rtQ==", - "license": "MIT", - "dependencies": { - "@parcel/watcher": "^2.5.1", - "@tailwindcss/node": "4.1.11", - "@tailwindcss/oxide": "4.1.11", - "enhanced-resolve": "^5.18.1", - "mri": "^1.2.0", - "picocolors": "^1.1.1", - "tailwindcss": "4.1.11" - }, - "bin": { - "tailwindcss": "dist/index.mjs" - } - }, - "node_modules/@tailwindcss/node": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.11.tgz", - "integrity": "sha512-yzhzuGRmv5QyU9qLNg4GTlYI6STedBWRE7NjxP45CsFYYq9taI0zJXZBMqIC/c8fViNLhmrbpSFS57EoxUmD6Q==", - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.3.0", - "enhanced-resolve": "^5.18.1", - "jiti": "^2.4.2", - "lightningcss": "1.30.1", - "magic-string": "^0.30.17", - "source-map-js": "^1.2.1", - "tailwindcss": "4.1.11" - } - }, - "node_modules/@tailwindcss/oxide": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.11.tgz", - "integrity": "sha512-Q69XzrtAhuyfHo+5/HMgr1lAiPP/G40OMFAnws7xcFEYqcypZmdW8eGXaOUIeOl1dzPJBPENXgbjsOyhg2nkrg==", - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "detect-libc": "^2.0.4", - "tar": "^7.4.3" - }, - "engines": { - "node": ">= 10" - }, - "optionalDependencies": { - "@tailwindcss/oxide-android-arm64": "4.1.11", - "@tailwindcss/oxide-darwin-arm64": "4.1.11", - "@tailwindcss/oxide-darwin-x64": "4.1.11", - "@tailwindcss/oxide-freebsd-x64": "4.1.11", - "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.11", - "@tailwindcss/oxide-linux-arm64-gnu": "4.1.11", - "@tailwindcss/oxide-linux-arm64-musl": "4.1.11", - "@tailwindcss/oxide-linux-x64-gnu": "4.1.11", - "@tailwindcss/oxide-linux-x64-musl": "4.1.11", - "@tailwindcss/oxide-wasm32-wasi": "4.1.11", - "@tailwindcss/oxide-win32-arm64-msvc": "4.1.11", - "@tailwindcss/oxide-win32-x64-msvc": "4.1.11" - } - }, - "node_modules/@tailwindcss/oxide-android-arm64": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.11.tgz", - "integrity": "sha512-3IfFuATVRUMZZprEIx9OGDjG3Ou3jG4xQzNTvjDoKmU9JdmoCohQJ83MYd0GPnQIu89YoJqvMM0G3uqLRFtetg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-darwin-arm64": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.11.tgz", - "integrity": "sha512-ESgStEOEsyg8J5YcMb1xl8WFOXfeBmrhAwGsFxxB2CxY9evy63+AtpbDLAyRkJnxLy2WsD1qF13E97uQyP1lfQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-darwin-x64": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.11.tgz", - "integrity": "sha512-EgnK8kRchgmgzG6jE10UQNaH9Mwi2n+yw1jWmof9Vyg2lpKNX2ioe7CJdf9M5f8V9uaQxInenZkOxnTVL3fhAw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-freebsd-x64": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.11.tgz", - "integrity": "sha512-xdqKtbpHs7pQhIKmqVpxStnY1skuNh4CtbcyOHeX1YBE0hArj2romsFGb6yUmzkq/6M24nkxDqU8GYrKrz+UcA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.11.tgz", - "integrity": "sha512-ryHQK2eyDYYMwB5wZL46uoxz2zzDZsFBwfjssgB7pzytAeCCa6glsiJGjhTEddq/4OsIjsLNMAiMlHNYnkEEeg==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.11.tgz", - "integrity": "sha512-mYwqheq4BXF83j/w75ewkPJmPZIqqP1nhoghS9D57CLjsh3Nfq0m4ftTotRYtGnZd3eCztgbSPJ9QhfC91gDZQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm64-musl": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.11.tgz", - "integrity": "sha512-m/NVRFNGlEHJrNVk3O6I9ggVuNjXHIPoD6bqay/pubtYC9QIdAMpS+cswZQPBLvVvEF6GtSNONbDkZrjWZXYNQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-x64-gnu": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.11.tgz", - "integrity": "sha512-YW6sblI7xukSD2TdbbaeQVDysIm/UPJtObHJHKxDEcW2exAtY47j52f8jZXkqE1krdnkhCMGqP3dbniu1Te2Fg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-x64-musl": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.11.tgz", - "integrity": "sha512-e3C/RRhGunWYNC3aSF7exsQkdXzQ/M+aYuZHKnw4U7KQwTJotnWsGOIVih0s2qQzmEzOFIJ3+xt7iq67K/p56Q==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.11.tgz", - "integrity": "sha512-Xo1+/GU0JEN/C/dvcammKHzeM6NqKovG+6921MR6oadee5XPBaKOumrJCXvopJ/Qb5TH7LX/UAywbqrP4lax0g==", - "bundleDependencies": [ - "@napi-rs/wasm-runtime", - "@emnapi/core", - "@emnapi/runtime", - "@tybys/wasm-util", - "@emnapi/wasi-threads", - "tslib" - ], - "cpu": [ - "wasm32" - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "^1.4.3", - "@emnapi/runtime": "^1.4.3", - "@emnapi/wasi-threads": "^1.0.2", - "@napi-rs/wasm-runtime": "^0.2.11", - "@tybys/wasm-util": "^0.9.0", - "tslib": "^2.8.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core": { - "version": "1.4.3", - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/wasi-threads": "1.0.2", - "tslib": "^2.4.0" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime": { - "version": "1.4.3", - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads": { - "version": "1.0.2", - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": { - "version": "0.2.11", - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "^1.4.3", - "@emnapi/runtime": "^1.4.3", - "@tybys/wasm-util": "^0.9.0" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": { - "version": "0.9.0", - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib": { - "version": "2.8.0", - "inBundle": true, - "license": "0BSD", - "optional": true - }, - "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.11.tgz", - "integrity": "sha512-UgKYx5PwEKrac3GPNPf6HVMNhUIGuUh4wlDFR2jYYdkX6pL/rn73zTq/4pzUm8fOjAn5L8zDeHp9iXmUGOXZ+w==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-win32-x64-msvc": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.11.tgz", - "integrity": "sha512-YfHoggn1j0LK7wR82TOucWc5LDCguHnoS879idHekmmiR7g9HUtMw9MI0NHatS28u/Xlkfi9w5RJWgz2Dl+5Qg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide/node_modules/detect-libc": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", - "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", - "license": "Apache-2.0", - "engines": { - "node": ">=8" - } - }, - "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/chownr": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", - "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, - "node_modules/detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", - "license": "Apache-2.0", - "bin": { - "detect-libc": "bin/detect-libc.js" - }, - "engines": { - "node": ">=0.10" - } - }, - "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/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/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/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-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-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/jiti": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", - "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", - "license": "MIT", - "bin": { - "jiti": "lib/jiti-cli.mjs" - } - }, - "node_modules/lightningcss": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz", - "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==", - "license": "MPL-2.0", - "dependencies": { - "detect-libc": "^2.0.3" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "optionalDependencies": { - "lightningcss-darwin-arm64": "1.30.1", - "lightningcss-darwin-x64": "1.30.1", - "lightningcss-freebsd-x64": "1.30.1", - "lightningcss-linux-arm-gnueabihf": "1.30.1", - "lightningcss-linux-arm64-gnu": "1.30.1", - "lightningcss-linux-arm64-musl": "1.30.1", - "lightningcss-linux-x64-gnu": "1.30.1", - "lightningcss-linux-x64-musl": "1.30.1", - "lightningcss-win32-arm64-msvc": "1.30.1", - "lightningcss-win32-x64-msvc": "1.30.1" - } - }, - "node_modules/lightningcss-darwin-arm64": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz", - "integrity": "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-darwin-x64": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz", - "integrity": "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-freebsd-x64": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz", - "integrity": "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz", - "integrity": "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==", - "cpu": [ - "arm" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz", - "integrity": "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz", - "integrity": "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz", - "integrity": "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-musl": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz", - "integrity": "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz", - "integrity": "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz", - "integrity": "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss/node_modules/detect-libc": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", - "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", - "license": "Apache-2.0", - "engines": { - "node": ">=8" - } - }, - "node_modules/magic-string": { - "version": "0.30.17", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", - "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0" - } - }, - "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/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/minizlib": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", - "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", - "license": "MIT", - "dependencies": { - "minipass": "^7.1.2" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/mri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", - "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/node-addon-api": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", - "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", - "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/picomatch": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", - "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "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/tailwindcss": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.11.tgz", - "integrity": "sha512-2E9TBm6MDD/xKYe+dvJZAmg3yxIEDNRc0jwlNyDg/4Fil2QcSLjFKGVff0lAf1jjeaArlG/M75Ey/EYr/OJtBA==", - "license": "MIT" - }, - "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/tar": { - "version": "7.5.13", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.13.tgz", - "integrity": "sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng==", - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/fs-minipass": "^4.0.0", - "chownr": "^3.0.0", - "minipass": "^7.1.2", - "minizlib": "^3.1.0", - "yallist": "^5.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "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/yallist": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", - "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - } - } -} diff --git a/src/components.abstractions/package.json b/src/components.abstractions/package.json deleted file mode 100644 index 59aeb296f..000000000 --- a/src/components.abstractions/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "dependencies": { - "@tailwindcss/cli": "^4.1.11", - "tailwindcss": "^4.1.11" - } -} diff --git a/src/components.siem.communication/ctrl/apax.yml b/src/components.siem.communication/ctrl/apax.yml index 2d44d0a1b..391b1e229 100644 --- a/src/components.siem.communication/ctrl/apax.yml +++ b/src/components.siem.communication/ctrl/apax.yml @@ -9,7 +9,7 @@ files: registries: "@inxton": "https://npm.pkg.github.com/" catalogs: - "@inxton/ax.catalog": '0.0.51' + "@inxton/ax.catalog": '0.0.52' devDependencies: "@inxton/ax-sdk": '0.0.0-dev.0' dependencies: diff --git a/src/data/package-lock.json b/src/data/package-lock.json deleted file mode 100644 index a4f78bc8b..000000000 --- a/src/data/package-lock.json +++ /dev/null @@ -1,1174 +0,0 @@ -{ - "name": "data", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "dependencies": { - "@tailwindcss/cli": "^4.1.11", - "tailwindcss": "^4.1.11" - } - }, - "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/@isaacs/fs-minipass": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", - "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", - "license": "ISC", - "dependencies": { - "minipass": "^7.0.4" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.12", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz", - "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==", - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "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/sourcemap-codec": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz", - "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==", - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.29", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz", - "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==", - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@parcel/watcher": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", - "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==", - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "detect-libc": "^1.0.3", - "is-glob": "^4.0.3", - "micromatch": "^4.0.5", - "node-addon-api": "^7.0.0" - }, - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "optionalDependencies": { - "@parcel/watcher-android-arm64": "2.5.1", - "@parcel/watcher-darwin-arm64": "2.5.1", - "@parcel/watcher-darwin-x64": "2.5.1", - "@parcel/watcher-freebsd-x64": "2.5.1", - "@parcel/watcher-linux-arm-glibc": "2.5.1", - "@parcel/watcher-linux-arm-musl": "2.5.1", - "@parcel/watcher-linux-arm64-glibc": "2.5.1", - "@parcel/watcher-linux-arm64-musl": "2.5.1", - "@parcel/watcher-linux-x64-glibc": "2.5.1", - "@parcel/watcher-linux-x64-musl": "2.5.1", - "@parcel/watcher-win32-arm64": "2.5.1", - "@parcel/watcher-win32-ia32": "2.5.1", - "@parcel/watcher-win32-x64": "2.5.1" - } - }, - "node_modules/@parcel/watcher-android-arm64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", - "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-darwin-arm64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz", - "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-darwin-x64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", - "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-freebsd-x64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", - "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm-glibc": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", - "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm-musl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", - "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm64-glibc": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz", - "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm64-musl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz", - "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-x64-glibc": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz", - "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-x64-musl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz", - "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-win32-arm64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz", - "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-win32-ia32": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz", - "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-win32-x64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz", - "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@tailwindcss/cli": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/cli/-/cli-4.1.11.tgz", - "integrity": "sha512-7RAFOrVaXCFz5ooEG36Kbh+sMJiI2j4+Ozp71smgjnLfBRu7DTfoq8DsTvzse2/6nDeo2M3vS/FGaxfDgr3rtQ==", - "license": "MIT", - "dependencies": { - "@parcel/watcher": "^2.5.1", - "@tailwindcss/node": "4.1.11", - "@tailwindcss/oxide": "4.1.11", - "enhanced-resolve": "^5.18.1", - "mri": "^1.2.0", - "picocolors": "^1.1.1", - "tailwindcss": "4.1.11" - }, - "bin": { - "tailwindcss": "dist/index.mjs" - } - }, - "node_modules/@tailwindcss/node": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.11.tgz", - "integrity": "sha512-yzhzuGRmv5QyU9qLNg4GTlYI6STedBWRE7NjxP45CsFYYq9taI0zJXZBMqIC/c8fViNLhmrbpSFS57EoxUmD6Q==", - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.3.0", - "enhanced-resolve": "^5.18.1", - "jiti": "^2.4.2", - "lightningcss": "1.30.1", - "magic-string": "^0.30.17", - "source-map-js": "^1.2.1", - "tailwindcss": "4.1.11" - } - }, - "node_modules/@tailwindcss/oxide": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.11.tgz", - "integrity": "sha512-Q69XzrtAhuyfHo+5/HMgr1lAiPP/G40OMFAnws7xcFEYqcypZmdW8eGXaOUIeOl1dzPJBPENXgbjsOyhg2nkrg==", - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "detect-libc": "^2.0.4", - "tar": "^7.4.3" - }, - "engines": { - "node": ">= 10" - }, - "optionalDependencies": { - "@tailwindcss/oxide-android-arm64": "4.1.11", - "@tailwindcss/oxide-darwin-arm64": "4.1.11", - "@tailwindcss/oxide-darwin-x64": "4.1.11", - "@tailwindcss/oxide-freebsd-x64": "4.1.11", - "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.11", - "@tailwindcss/oxide-linux-arm64-gnu": "4.1.11", - "@tailwindcss/oxide-linux-arm64-musl": "4.1.11", - "@tailwindcss/oxide-linux-x64-gnu": "4.1.11", - "@tailwindcss/oxide-linux-x64-musl": "4.1.11", - "@tailwindcss/oxide-wasm32-wasi": "4.1.11", - "@tailwindcss/oxide-win32-arm64-msvc": "4.1.11", - "@tailwindcss/oxide-win32-x64-msvc": "4.1.11" - } - }, - "node_modules/@tailwindcss/oxide-android-arm64": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.11.tgz", - "integrity": "sha512-3IfFuATVRUMZZprEIx9OGDjG3Ou3jG4xQzNTvjDoKmU9JdmoCohQJ83MYd0GPnQIu89YoJqvMM0G3uqLRFtetg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-darwin-arm64": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.11.tgz", - "integrity": "sha512-ESgStEOEsyg8J5YcMb1xl8WFOXfeBmrhAwGsFxxB2CxY9evy63+AtpbDLAyRkJnxLy2WsD1qF13E97uQyP1lfQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-darwin-x64": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.11.tgz", - "integrity": "sha512-EgnK8kRchgmgzG6jE10UQNaH9Mwi2n+yw1jWmof9Vyg2lpKNX2ioe7CJdf9M5f8V9uaQxInenZkOxnTVL3fhAw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-freebsd-x64": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.11.tgz", - "integrity": "sha512-xdqKtbpHs7pQhIKmqVpxStnY1skuNh4CtbcyOHeX1YBE0hArj2romsFGb6yUmzkq/6M24nkxDqU8GYrKrz+UcA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.11.tgz", - "integrity": "sha512-ryHQK2eyDYYMwB5wZL46uoxz2zzDZsFBwfjssgB7pzytAeCCa6glsiJGjhTEddq/4OsIjsLNMAiMlHNYnkEEeg==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.11.tgz", - "integrity": "sha512-mYwqheq4BXF83j/w75ewkPJmPZIqqP1nhoghS9D57CLjsh3Nfq0m4ftTotRYtGnZd3eCztgbSPJ9QhfC91gDZQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm64-musl": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.11.tgz", - "integrity": "sha512-m/NVRFNGlEHJrNVk3O6I9ggVuNjXHIPoD6bqay/pubtYC9QIdAMpS+cswZQPBLvVvEF6GtSNONbDkZrjWZXYNQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-x64-gnu": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.11.tgz", - "integrity": "sha512-YW6sblI7xukSD2TdbbaeQVDysIm/UPJtObHJHKxDEcW2exAtY47j52f8jZXkqE1krdnkhCMGqP3dbniu1Te2Fg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-x64-musl": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.11.tgz", - "integrity": "sha512-e3C/RRhGunWYNC3aSF7exsQkdXzQ/M+aYuZHKnw4U7KQwTJotnWsGOIVih0s2qQzmEzOFIJ3+xt7iq67K/p56Q==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.11.tgz", - "integrity": "sha512-Xo1+/GU0JEN/C/dvcammKHzeM6NqKovG+6921MR6oadee5XPBaKOumrJCXvopJ/Qb5TH7LX/UAywbqrP4lax0g==", - "bundleDependencies": [ - "@napi-rs/wasm-runtime", - "@emnapi/core", - "@emnapi/runtime", - "@tybys/wasm-util", - "@emnapi/wasi-threads", - "tslib" - ], - "cpu": [ - "wasm32" - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "^1.4.3", - "@emnapi/runtime": "^1.4.3", - "@emnapi/wasi-threads": "^1.0.2", - "@napi-rs/wasm-runtime": "^0.2.11", - "@tybys/wasm-util": "^0.9.0", - "tslib": "^2.8.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core": { - "version": "1.4.3", - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/wasi-threads": "1.0.2", - "tslib": "^2.4.0" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime": { - "version": "1.4.3", - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads": { - "version": "1.0.2", - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": { - "version": "0.2.11", - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "^1.4.3", - "@emnapi/runtime": "^1.4.3", - "@tybys/wasm-util": "^0.9.0" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": { - "version": "0.9.0", - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib": { - "version": "2.8.0", - "inBundle": true, - "license": "0BSD", - "optional": true - }, - "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.11.tgz", - "integrity": "sha512-UgKYx5PwEKrac3GPNPf6HVMNhUIGuUh4wlDFR2jYYdkX6pL/rn73zTq/4pzUm8fOjAn5L8zDeHp9iXmUGOXZ+w==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-win32-x64-msvc": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.11.tgz", - "integrity": "sha512-YfHoggn1j0LK7wR82TOucWc5LDCguHnoS879idHekmmiR7g9HUtMw9MI0NHatS28u/Xlkfi9w5RJWgz2Dl+5Qg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide/node_modules/detect-libc": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", - "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", - "license": "Apache-2.0", - "engines": { - "node": ">=8" - } - }, - "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/chownr": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", - "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, - "node_modules/detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", - "license": "Apache-2.0", - "bin": { - "detect-libc": "bin/detect-libc.js" - }, - "engines": { - "node": ">=0.10" - } - }, - "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/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/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/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-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-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/jiti": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", - "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", - "license": "MIT", - "bin": { - "jiti": "lib/jiti-cli.mjs" - } - }, - "node_modules/lightningcss": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz", - "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==", - "license": "MPL-2.0", - "dependencies": { - "detect-libc": "^2.0.3" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "optionalDependencies": { - "lightningcss-darwin-arm64": "1.30.1", - "lightningcss-darwin-x64": "1.30.1", - "lightningcss-freebsd-x64": "1.30.1", - "lightningcss-linux-arm-gnueabihf": "1.30.1", - "lightningcss-linux-arm64-gnu": "1.30.1", - "lightningcss-linux-arm64-musl": "1.30.1", - "lightningcss-linux-x64-gnu": "1.30.1", - "lightningcss-linux-x64-musl": "1.30.1", - "lightningcss-win32-arm64-msvc": "1.30.1", - "lightningcss-win32-x64-msvc": "1.30.1" - } - }, - "node_modules/lightningcss-darwin-arm64": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz", - "integrity": "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-darwin-x64": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz", - "integrity": "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-freebsd-x64": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz", - "integrity": "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz", - "integrity": "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==", - "cpu": [ - "arm" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz", - "integrity": "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz", - "integrity": "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz", - "integrity": "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-musl": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz", - "integrity": "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz", - "integrity": "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz", - "integrity": "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss/node_modules/detect-libc": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", - "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", - "license": "Apache-2.0", - "engines": { - "node": ">=8" - } - }, - "node_modules/magic-string": { - "version": "0.30.17", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", - "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0" - } - }, - "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/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/minizlib": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", - "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", - "license": "MIT", - "dependencies": { - "minipass": "^7.1.2" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/mri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", - "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/node-addon-api": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", - "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", - "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/picomatch": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", - "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "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/tailwindcss": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.11.tgz", - "integrity": "sha512-2E9TBm6MDD/xKYe+dvJZAmg3yxIEDNRc0jwlNyDg/4Fil2QcSLjFKGVff0lAf1jjeaArlG/M75Ey/EYr/OJtBA==", - "license": "MIT" - }, - "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/tar": { - "version": "7.5.13", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.13.tgz", - "integrity": "sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng==", - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/fs-minipass": "^4.0.0", - "chownr": "^3.0.0", - "minipass": "^7.1.2", - "minizlib": "^3.1.0", - "yallist": "^5.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "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/yallist": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", - "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - } - } -} diff --git a/src/data/package.json b/src/data/package.json deleted file mode 100644 index 59aeb296f..000000000 --- a/src/data/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "dependencies": { - "@tailwindcss/cli": "^4.1.11", - "tailwindcss": "^4.1.11" - } -} diff --git a/src/data/src/AXOpen.Data.Blazor/package-lock.json b/src/data/src/AXOpen.Data.Blazor/package-lock.json deleted file mode 100644 index a1067c7ca..000000000 --- a/src/data/src/AXOpen.Data.Blazor/package-lock.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "requires": true, - "lockfileVersion": 1, - "dependencies": { - "bootstrap-icons": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.10.3.tgz", - "integrity": "sha512-7Qvj0j0idEm/DdX9Q0CpxAnJYqBCFCiUI6qzSPYfERMcokVuV9Mdm/AJiVZI8+Gawe4h/l6zFcOzvV7oXCZArw==" - } - } -} diff --git a/src/inspectors/package-lock.json b/src/inspectors/package-lock.json deleted file mode 100644 index 75f8225f6..000000000 --- a/src/inspectors/package-lock.json +++ /dev/null @@ -1,1174 +0,0 @@ -{ - "name": "inspectors", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "dependencies": { - "@tailwindcss/cli": "^4.1.11", - "tailwindcss": "^4.1.11" - } - }, - "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/@isaacs/fs-minipass": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", - "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", - "license": "ISC", - "dependencies": { - "minipass": "^7.0.4" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.12", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz", - "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==", - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "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/sourcemap-codec": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz", - "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==", - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.29", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz", - "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==", - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@parcel/watcher": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", - "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==", - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "detect-libc": "^1.0.3", - "is-glob": "^4.0.3", - "micromatch": "^4.0.5", - "node-addon-api": "^7.0.0" - }, - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "optionalDependencies": { - "@parcel/watcher-android-arm64": "2.5.1", - "@parcel/watcher-darwin-arm64": "2.5.1", - "@parcel/watcher-darwin-x64": "2.5.1", - "@parcel/watcher-freebsd-x64": "2.5.1", - "@parcel/watcher-linux-arm-glibc": "2.5.1", - "@parcel/watcher-linux-arm-musl": "2.5.1", - "@parcel/watcher-linux-arm64-glibc": "2.5.1", - "@parcel/watcher-linux-arm64-musl": "2.5.1", - "@parcel/watcher-linux-x64-glibc": "2.5.1", - "@parcel/watcher-linux-x64-musl": "2.5.1", - "@parcel/watcher-win32-arm64": "2.5.1", - "@parcel/watcher-win32-ia32": "2.5.1", - "@parcel/watcher-win32-x64": "2.5.1" - } - }, - "node_modules/@parcel/watcher-android-arm64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", - "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-darwin-arm64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz", - "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-darwin-x64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", - "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-freebsd-x64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", - "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm-glibc": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", - "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm-musl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", - "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm64-glibc": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz", - "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm64-musl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz", - "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-x64-glibc": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz", - "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-x64-musl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz", - "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-win32-arm64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz", - "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-win32-ia32": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz", - "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-win32-x64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz", - "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@tailwindcss/cli": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/cli/-/cli-4.1.11.tgz", - "integrity": "sha512-7RAFOrVaXCFz5ooEG36Kbh+sMJiI2j4+Ozp71smgjnLfBRu7DTfoq8DsTvzse2/6nDeo2M3vS/FGaxfDgr3rtQ==", - "license": "MIT", - "dependencies": { - "@parcel/watcher": "^2.5.1", - "@tailwindcss/node": "4.1.11", - "@tailwindcss/oxide": "4.1.11", - "enhanced-resolve": "^5.18.1", - "mri": "^1.2.0", - "picocolors": "^1.1.1", - "tailwindcss": "4.1.11" - }, - "bin": { - "tailwindcss": "dist/index.mjs" - } - }, - "node_modules/@tailwindcss/node": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.11.tgz", - "integrity": "sha512-yzhzuGRmv5QyU9qLNg4GTlYI6STedBWRE7NjxP45CsFYYq9taI0zJXZBMqIC/c8fViNLhmrbpSFS57EoxUmD6Q==", - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.3.0", - "enhanced-resolve": "^5.18.1", - "jiti": "^2.4.2", - "lightningcss": "1.30.1", - "magic-string": "^0.30.17", - "source-map-js": "^1.2.1", - "tailwindcss": "4.1.11" - } - }, - "node_modules/@tailwindcss/oxide": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.11.tgz", - "integrity": "sha512-Q69XzrtAhuyfHo+5/HMgr1lAiPP/G40OMFAnws7xcFEYqcypZmdW8eGXaOUIeOl1dzPJBPENXgbjsOyhg2nkrg==", - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "detect-libc": "^2.0.4", - "tar": "^7.4.3" - }, - "engines": { - "node": ">= 10" - }, - "optionalDependencies": { - "@tailwindcss/oxide-android-arm64": "4.1.11", - "@tailwindcss/oxide-darwin-arm64": "4.1.11", - "@tailwindcss/oxide-darwin-x64": "4.1.11", - "@tailwindcss/oxide-freebsd-x64": "4.1.11", - "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.11", - "@tailwindcss/oxide-linux-arm64-gnu": "4.1.11", - "@tailwindcss/oxide-linux-arm64-musl": "4.1.11", - "@tailwindcss/oxide-linux-x64-gnu": "4.1.11", - "@tailwindcss/oxide-linux-x64-musl": "4.1.11", - "@tailwindcss/oxide-wasm32-wasi": "4.1.11", - "@tailwindcss/oxide-win32-arm64-msvc": "4.1.11", - "@tailwindcss/oxide-win32-x64-msvc": "4.1.11" - } - }, - "node_modules/@tailwindcss/oxide-android-arm64": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.11.tgz", - "integrity": "sha512-3IfFuATVRUMZZprEIx9OGDjG3Ou3jG4xQzNTvjDoKmU9JdmoCohQJ83MYd0GPnQIu89YoJqvMM0G3uqLRFtetg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-darwin-arm64": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.11.tgz", - "integrity": "sha512-ESgStEOEsyg8J5YcMb1xl8WFOXfeBmrhAwGsFxxB2CxY9evy63+AtpbDLAyRkJnxLy2WsD1qF13E97uQyP1lfQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-darwin-x64": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.11.tgz", - "integrity": "sha512-EgnK8kRchgmgzG6jE10UQNaH9Mwi2n+yw1jWmof9Vyg2lpKNX2ioe7CJdf9M5f8V9uaQxInenZkOxnTVL3fhAw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-freebsd-x64": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.11.tgz", - "integrity": "sha512-xdqKtbpHs7pQhIKmqVpxStnY1skuNh4CtbcyOHeX1YBE0hArj2romsFGb6yUmzkq/6M24nkxDqU8GYrKrz+UcA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.11.tgz", - "integrity": "sha512-ryHQK2eyDYYMwB5wZL46uoxz2zzDZsFBwfjssgB7pzytAeCCa6glsiJGjhTEddq/4OsIjsLNMAiMlHNYnkEEeg==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.11.tgz", - "integrity": "sha512-mYwqheq4BXF83j/w75ewkPJmPZIqqP1nhoghS9D57CLjsh3Nfq0m4ftTotRYtGnZd3eCztgbSPJ9QhfC91gDZQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm64-musl": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.11.tgz", - "integrity": "sha512-m/NVRFNGlEHJrNVk3O6I9ggVuNjXHIPoD6bqay/pubtYC9QIdAMpS+cswZQPBLvVvEF6GtSNONbDkZrjWZXYNQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-x64-gnu": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.11.tgz", - "integrity": "sha512-YW6sblI7xukSD2TdbbaeQVDysIm/UPJtObHJHKxDEcW2exAtY47j52f8jZXkqE1krdnkhCMGqP3dbniu1Te2Fg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-x64-musl": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.11.tgz", - "integrity": "sha512-e3C/RRhGunWYNC3aSF7exsQkdXzQ/M+aYuZHKnw4U7KQwTJotnWsGOIVih0s2qQzmEzOFIJ3+xt7iq67K/p56Q==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.11.tgz", - "integrity": "sha512-Xo1+/GU0JEN/C/dvcammKHzeM6NqKovG+6921MR6oadee5XPBaKOumrJCXvopJ/Qb5TH7LX/UAywbqrP4lax0g==", - "bundleDependencies": [ - "@napi-rs/wasm-runtime", - "@emnapi/core", - "@emnapi/runtime", - "@tybys/wasm-util", - "@emnapi/wasi-threads", - "tslib" - ], - "cpu": [ - "wasm32" - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "^1.4.3", - "@emnapi/runtime": "^1.4.3", - "@emnapi/wasi-threads": "^1.0.2", - "@napi-rs/wasm-runtime": "^0.2.11", - "@tybys/wasm-util": "^0.9.0", - "tslib": "^2.8.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core": { - "version": "1.4.3", - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/wasi-threads": "1.0.2", - "tslib": "^2.4.0" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime": { - "version": "1.4.3", - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads": { - "version": "1.0.2", - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": { - "version": "0.2.11", - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "^1.4.3", - "@emnapi/runtime": "^1.4.3", - "@tybys/wasm-util": "^0.9.0" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": { - "version": "0.9.0", - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib": { - "version": "2.8.0", - "inBundle": true, - "license": "0BSD", - "optional": true - }, - "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.11.tgz", - "integrity": "sha512-UgKYx5PwEKrac3GPNPf6HVMNhUIGuUh4wlDFR2jYYdkX6pL/rn73zTq/4pzUm8fOjAn5L8zDeHp9iXmUGOXZ+w==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-win32-x64-msvc": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.11.tgz", - "integrity": "sha512-YfHoggn1j0LK7wR82TOucWc5LDCguHnoS879idHekmmiR7g9HUtMw9MI0NHatS28u/Xlkfi9w5RJWgz2Dl+5Qg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide/node_modules/detect-libc": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", - "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", - "license": "Apache-2.0", - "engines": { - "node": ">=8" - } - }, - "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/chownr": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", - "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, - "node_modules/detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", - "license": "Apache-2.0", - "bin": { - "detect-libc": "bin/detect-libc.js" - }, - "engines": { - "node": ">=0.10" - } - }, - "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/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/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/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-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-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/jiti": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", - "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", - "license": "MIT", - "bin": { - "jiti": "lib/jiti-cli.mjs" - } - }, - "node_modules/lightningcss": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz", - "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==", - "license": "MPL-2.0", - "dependencies": { - "detect-libc": "^2.0.3" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "optionalDependencies": { - "lightningcss-darwin-arm64": "1.30.1", - "lightningcss-darwin-x64": "1.30.1", - "lightningcss-freebsd-x64": "1.30.1", - "lightningcss-linux-arm-gnueabihf": "1.30.1", - "lightningcss-linux-arm64-gnu": "1.30.1", - "lightningcss-linux-arm64-musl": "1.30.1", - "lightningcss-linux-x64-gnu": "1.30.1", - "lightningcss-linux-x64-musl": "1.30.1", - "lightningcss-win32-arm64-msvc": "1.30.1", - "lightningcss-win32-x64-msvc": "1.30.1" - } - }, - "node_modules/lightningcss-darwin-arm64": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz", - "integrity": "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-darwin-x64": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz", - "integrity": "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-freebsd-x64": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz", - "integrity": "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz", - "integrity": "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==", - "cpu": [ - "arm" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz", - "integrity": "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz", - "integrity": "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz", - "integrity": "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-musl": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz", - "integrity": "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz", - "integrity": "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz", - "integrity": "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss/node_modules/detect-libc": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", - "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", - "license": "Apache-2.0", - "engines": { - "node": ">=8" - } - }, - "node_modules/magic-string": { - "version": "0.30.17", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", - "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0" - } - }, - "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/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/minizlib": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", - "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", - "license": "MIT", - "dependencies": { - "minipass": "^7.1.2" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/mri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", - "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/node-addon-api": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", - "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", - "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/picomatch": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", - "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "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/tailwindcss": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.11.tgz", - "integrity": "sha512-2E9TBm6MDD/xKYe+dvJZAmg3yxIEDNRc0jwlNyDg/4Fil2QcSLjFKGVff0lAf1jjeaArlG/M75Ey/EYr/OJtBA==", - "license": "MIT" - }, - "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/tar": { - "version": "7.5.13", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.13.tgz", - "integrity": "sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng==", - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/fs-minipass": "^4.0.0", - "chownr": "^3.0.0", - "minipass": "^7.1.2", - "minizlib": "^3.1.0", - "yallist": "^5.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "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/yallist": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", - "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - } - } -} diff --git a/src/inspectors/package.json b/src/inspectors/package.json deleted file mode 100644 index 59aeb296f..000000000 --- a/src/inspectors/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "dependencies": { - "@tailwindcss/cli": "^4.1.11", - "tailwindcss": "^4.1.11" - } -} diff --git a/src/sdk-ax/ctrl/apax.yml b/src/sdk-ax/ctrl/apax.yml index a4eb51863..bb2646427 100644 --- a/src/sdk-ax/ctrl/apax.yml +++ b/src/sdk-ax/ctrl/apax.yml @@ -6,27 +6,27 @@ files: registries: "@inxton": "https://npm.pkg.github.com/" catalogs: - "@inxton/ax.catalog": '0.0.51' + "@inxton/ax.catalog": '0.0.52' dependencies: '@ax/apax-build': 2.2.60 '@ax/axunitst': 9.4.8 - '@ax/certificate-management': 2.0.0 - '@ax/diagnostic-buffer': 2.1.1 + '@ax/certificate-management': 2.0.1 + '@ax/diagnostic-buffer': 2.2.0 '@ax/hw-s7-1500': 4.4.1 '@ax/hwc': 4.4.1 - '@ax/hwld': 3.4.0 - '@ax/mod': 1.13.21 - '@ax/mon': 1.13.21 - '@ax/plc-info': 4.1.1 - '@ax/sdb': 1.13.21 + '@ax/hwld': 3.5.0 + '@ax/mod': 1.14.13 + '@ax/mon': 1.14.13 + '@ax/plc-info': 4.2.0 + '@ax/sdb': 1.14.13 '@ax/simatic-package-tool': 2.0.17 - '@ax/sld': 3.6.3 - '@ax/st-ls': 11.4.57 + '@ax/sld': 3.8.3 + '@ax/st-ls': 11.5.53 '@ax/st-resources.stc-plugin': 4.0.3 - '@ax/stc': 11.4.57 - '@ax/target-llvm': 11.4.57 - '@ax/target-mc7plus': 11.4.57 - '@ax/trace': 3.3.1 + '@ax/stc': 11.5.53 + '@ax/target-llvm': 11.5.53 + '@ax/target-mc7plus': 11.5.53 + '@ax/trace': 3.4.0 installStrategy: strict apaxVersion: 3.5.0 scripts: diff --git a/src/styling/src/package-lock.json b/src/styling/src/package-lock.json index 498ed0899..41135c11f 100644 --- a/src/styling/src/package-lock.json +++ b/src/styling/src/package-lock.json @@ -5,8 +5,8 @@ "packages": { "": { "dependencies": { - "@tailwindcss/cli": "^4.2.2", - "tailwindcss": "^4.2.2" + "@tailwindcss/cli": "^4.3.0", + "tailwindcss": "^4.3.0" } }, "node_modules/@jridgewell/gen-mapping": { @@ -350,65 +350,65 @@ } }, "node_modules/@tailwindcss/cli": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/cli/-/cli-4.2.2.tgz", - "integrity": "sha512-iJS+8kAFZ8HPqnh0O5DHCLjo4L6dD97DBQEkrhfSO4V96xeefUus2jqsBs1dUMt3OU9Ks4qIkiY0mpL5UW+4LQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/cli/-/cli-4.3.0.tgz", + "integrity": "sha512-X9kdlqyMopO9fewbgHsEeuy31YzMHbdZ9VsKt004tB+mxSg1CNbyhZYCzvhciN0AM4R4b5lvIprPjtNq7iQxpQ==", "license": "MIT", "dependencies": { "@parcel/watcher": "^2.5.1", - "@tailwindcss/node": "4.2.2", - "@tailwindcss/oxide": "4.2.2", - "enhanced-resolve": "^5.19.0", + "@tailwindcss/node": "4.3.0", + "@tailwindcss/oxide": "4.3.0", + "enhanced-resolve": "^5.21.0", "mri": "^1.2.0", "picocolors": "^1.1.1", - "tailwindcss": "4.2.2" + "tailwindcss": "4.3.0" }, "bin": { "tailwindcss": "dist/index.mjs" } }, "node_modules/@tailwindcss/node": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.2.2.tgz", - "integrity": "sha512-pXS+wJ2gZpVXqFaUEjojq7jzMpTGf8rU6ipJz5ovJV6PUGmlJ+jvIwGrzdHdQ80Sg+wmQxUFuoW1UAAwHNEdFA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.0.tgz", + "integrity": "sha512-aFb4gUhFOgdh9AXo4IzBEOzBkkAxm9VigwDJnMIYv3lcfXCJVesNfbEaBl4BNgVRyid92AmdviqwBUBRKSeY3g==", "license": "MIT", "dependencies": { "@jridgewell/remapping": "^2.3.5", - "enhanced-resolve": "^5.19.0", + "enhanced-resolve": "^5.21.0", "jiti": "^2.6.1", "lightningcss": "1.32.0", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", - "tailwindcss": "4.2.2" + "tailwindcss": "4.3.0" } }, "node_modules/@tailwindcss/oxide": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.2.2.tgz", - "integrity": "sha512-qEUA07+E5kehxYp9BVMpq9E8vnJuBHfJEC0vPC5e7iL/hw7HR61aDKoVoKzrG+QKp56vhNZe4qwkRmMC0zDLvg==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.3.0.tgz", + "integrity": "sha512-F7HZGBeN9I0/AuuJS5PwcD8xayx5ri5GhjYUDBEVYUkexyA/giwbDNjRVrxSezE3T250OU2K/wp/ltWx3UOefg==", "license": "MIT", "engines": { "node": ">= 20" }, "optionalDependencies": { - "@tailwindcss/oxide-android-arm64": "4.2.2", - "@tailwindcss/oxide-darwin-arm64": "4.2.2", - "@tailwindcss/oxide-darwin-x64": "4.2.2", - "@tailwindcss/oxide-freebsd-x64": "4.2.2", - "@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.2", - "@tailwindcss/oxide-linux-arm64-gnu": "4.2.2", - "@tailwindcss/oxide-linux-arm64-musl": "4.2.2", - "@tailwindcss/oxide-linux-x64-gnu": "4.2.2", - "@tailwindcss/oxide-linux-x64-musl": "4.2.2", - "@tailwindcss/oxide-wasm32-wasi": "4.2.2", - "@tailwindcss/oxide-win32-arm64-msvc": "4.2.2", - "@tailwindcss/oxide-win32-x64-msvc": "4.2.2" + "@tailwindcss/oxide-android-arm64": "4.3.0", + "@tailwindcss/oxide-darwin-arm64": "4.3.0", + "@tailwindcss/oxide-darwin-x64": "4.3.0", + "@tailwindcss/oxide-freebsd-x64": "4.3.0", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.0", + "@tailwindcss/oxide-linux-arm64-gnu": "4.3.0", + "@tailwindcss/oxide-linux-arm64-musl": "4.3.0", + "@tailwindcss/oxide-linux-x64-gnu": "4.3.0", + "@tailwindcss/oxide-linux-x64-musl": "4.3.0", + "@tailwindcss/oxide-wasm32-wasi": "4.3.0", + "@tailwindcss/oxide-win32-arm64-msvc": "4.3.0", + "@tailwindcss/oxide-win32-x64-msvc": "4.3.0" } }, "node_modules/@tailwindcss/oxide-android-arm64": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.2.2.tgz", - "integrity": "sha512-dXGR1n+P3B6748jZO/SvHZq7qBOqqzQ+yFrXpoOWWALWndF9MoSKAT3Q0fYgAzYzGhxNYOoysRvYlpixRBBoDg==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.3.0.tgz", + "integrity": "sha512-TJPiq67tKlLuObP6RkwvVGDoxCMBVtDgKkLfa/uyj7/FyxvQwHS+UOnVrXXgbEsfUaMgiVvC4KbJnRr26ho4Ng==", "cpu": [ "arm64" ], @@ -422,9 +422,9 @@ } }, "node_modules/@tailwindcss/oxide-darwin-arm64": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.2.2.tgz", - "integrity": "sha512-iq9Qjr6knfMpZHj55/37ouZeykwbDqF21gPFtfnhCCKGDcPI/21FKC9XdMO/XyBM7qKORx6UIhGgg6jLl7BZlg==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.3.0.tgz", + "integrity": "sha512-oMN/WZRb+SO37BmUElEgeEWuU8E/HXRkiODxJxLe1UTHVXLrdVSgfaJV7pSlhRGMSOiXLuxTIjfsF3wYvz8cgQ==", "cpu": [ "arm64" ], @@ -438,9 +438,9 @@ } }, "node_modules/@tailwindcss/oxide-darwin-x64": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.2.2.tgz", - "integrity": "sha512-BlR+2c3nzc8f2G639LpL89YY4bdcIdUmiOOkv2GQv4/4M0vJlpXEa0JXNHhCHU7VWOKWT/CjqHdTP8aUuDJkuw==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.3.0.tgz", + "integrity": "sha512-N6CUmu4a6bKVADfw77p+iw6Yd9Q3OBhe0veaDX+QazfuVYlQsHfDgxBrsjQ/IW+zywL8mTrNd0SdJT/zgtvMdA==", "cpu": [ "x64" ], @@ -454,9 +454,9 @@ } }, "node_modules/@tailwindcss/oxide-freebsd-x64": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.2.2.tgz", - "integrity": "sha512-YUqUgrGMSu2CDO82hzlQ5qSb5xmx3RUrke/QgnoEx7KvmRJHQuZHZmZTLSuuHwFf0DJPybFMXMYf+WJdxHy/nQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.3.0.tgz", + "integrity": "sha512-zDL5hBkQdH5C6MpqbK3gQAgP80tsMwSI26vjOzjJtNCMUo0lFgOItzHKBIupOZNQxt3ouPH7RPhvNhiTfCe5CQ==", "cpu": [ "x64" ], @@ -470,9 +470,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.2.2.tgz", - "integrity": "sha512-FPdhvsW6g06T9BWT0qTwiVZYE2WIFo2dY5aCSpjG/S/u1tby+wXoslXS0kl3/KXnULlLr1E3NPRRw0g7t2kgaQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.3.0.tgz", + "integrity": "sha512-R06HdNi7A7OEoMsf6d4tjZ71RCWnZQPHj2mnotSFURjNLdBC+cIgXQ7l81CqeoiQftjf6OOblxXMInMgN2VzMA==", "cpu": [ "arm" ], @@ -486,9 +486,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.2.2.tgz", - "integrity": "sha512-4og1V+ftEPXGttOO7eCmW7VICmzzJWgMx+QXAJRAhjrSjumCwWqMfkDrNu1LXEQzNAwz28NCUpucgQPrR4S2yw==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.3.0.tgz", + "integrity": "sha512-qTJHELX8jetjhRQHCLilkVLmybpzNQAtaI/gaoVoidn/ufbNDbAo8KlK2J+yPoc8wQxvDxCmh/5lr8nC1+lTbg==", "cpu": [ "arm64" ], @@ -502,9 +502,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm64-musl": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.2.2.tgz", - "integrity": "sha512-oCfG/mS+/+XRlwNjnsNLVwnMWYH7tn/kYPsNPh+JSOMlnt93mYNCKHYzylRhI51X+TbR+ufNhhKKzm6QkqX8ag==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.3.0.tgz", + "integrity": "sha512-Z6sukiQsngnWO+l39X4pPbiWT81IC+PLKF+PHxIlyZbGNb9MODfYlXEVlFvej5BOZInWX01kVyzeLvHsXhfczQ==", "cpu": [ "arm64" ], @@ -518,9 +518,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-x64-gnu": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.2.2.tgz", - "integrity": "sha512-rTAGAkDgqbXHNp/xW0iugLVmX62wOp2PoE39BTCGKjv3Iocf6AFbRP/wZT/kuCxC9QBh9Pu8XPkv/zCZB2mcMg==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.3.0.tgz", + "integrity": "sha512-DRNdQRpSGzRGfARVuVkxvM8Q12nh19l4BF/G7zGA1oe+9wcC6saFBHTISrpIcKzhiXtSrlSrluCfvMuledoCTQ==", "cpu": [ "x64" ], @@ -534,9 +534,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-x64-musl": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.2.2.tgz", - "integrity": "sha512-XW3t3qwbIwiSyRCggeO2zxe3KWaEbM0/kW9e8+0XpBgyKU4ATYzcVSMKteZJ1iukJ3HgHBjbg9P5YPRCVUxlnQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.3.0.tgz", + "integrity": "sha512-Z0IADbDo8bh6I7h2IQMx601AdXBLfFpEdUotft86evd/8ZPflZe9COPO8Q1vw+pfLWIUo9zN/JGZvwuAJqduqg==", "cpu": [ "x64" ], @@ -550,9 +550,9 @@ } }, "node_modules/@tailwindcss/oxide-wasm32-wasi": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.2.2.tgz", - "integrity": "sha512-eKSztKsmEsn1O5lJ4ZAfyn41NfG7vzCg496YiGtMDV86jz1q/irhms5O0VrY6ZwTUkFy/EKG3RfWgxSI3VbZ8Q==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.3.0.tgz", + "integrity": "sha512-HNZGOUxEmElksYR7S6sC5jTeNGpobAsy9u7Gu0AskJ8/20FR9GqebUyB+HBcU/ax6BHuiuJi+Oda4B+YX6H1yA==", "bundleDependencies": [ "@napi-rs/wasm-runtime", "@emnapi/core", @@ -567,10 +567,10 @@ "license": "MIT", "optional": true, "dependencies": { - "@emnapi/core": "^1.8.1", - "@emnapi/runtime": "^1.8.1", - "@emnapi/wasi-threads": "^1.1.0", - "@napi-rs/wasm-runtime": "^1.1.1", + "@emnapi/core": "^1.10.0", + "@emnapi/runtime": "^1.10.0", + "@emnapi/wasi-threads": "^1.2.1", + "@napi-rs/wasm-runtime": "^1.1.4", "@tybys/wasm-util": "^0.10.1", "tslib": "^2.8.1" }, @@ -578,64 +578,10 @@ "node": ">=14.0.0" } }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core": { - "version": "1.7.1", - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/wasi-threads": "1.1.0", - "tslib": "^2.4.0" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime": { - "version": "1.7.1", - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads": { - "version": "1.1.0", - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": { - "version": "1.1.0", - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "^1.7.1", - "@emnapi/runtime": "^1.7.1", - "@tybys/wasm-util": "^0.10.1" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": { - "version": "0.10.1", - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib": { - "version": "2.8.1", - "inBundle": true, - "license": "0BSD", - "optional": true - }, "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.2.2.tgz", - "integrity": "sha512-qPmaQM4iKu5mxpsrWZMOZRgZv1tOZpUm+zdhhQP0VhJfyGGO3aUKdbh3gDZc/dPLQwW4eSqWGrrcWNBZWUWaXQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.0.tgz", + "integrity": "sha512-Pe+RPVTi1T+qymuuRpcdvwSVZjnll/f7n8gBxMMh3xLTctMDKqpdfGimbMyioqtLhUYZxdJ9wGNhV7MKHvgZsQ==", "cpu": [ "arm64" ], @@ -649,9 +595,9 @@ } }, "node_modules/@tailwindcss/oxide-win32-x64-msvc": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.2.2.tgz", - "integrity": "sha512-1T/37VvI7WyH66b+vqHj/cLwnCxt7Qt3WFu5Q8hk65aOvlwAhs7rAp1VkulBJw/N4tMirXjVnylTR72uI0HGcA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.3.0.tgz", + "integrity": "sha512-Mvrf2kXW/yeW/OTezZlCGOirXRcUuLIBx/5Y12BaPM7wJoryG6dfS/NJL8aBPqtTEx/Vm4T4vKzFUcKDT+TKUA==", "cpu": [ "x64" ], @@ -674,13 +620,13 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.20.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.20.1.tgz", - "integrity": "sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA==", + "version": "5.22.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.22.1.tgz", + "integrity": "sha512-6QEuw3zoX1SJQc7b87aBXke/no+mG2bTBgw29gWMQonLmpEkWoCAVkl+M49e48AZlWzxiDzDZzYdp6kobcyLww==", "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", - "tapable": "^2.3.0" + "tapable": "^2.3.3" }, "engines": { "node": ">=10.13.0" @@ -714,9 +660,9 @@ } }, "node_modules/jiti": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", - "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", + "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==", "license": "MIT", "bin": { "jiti": "lib/jiti-cli.mjs" @@ -1023,15 +969,15 @@ } }, "node_modules/tailwindcss": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.2.tgz", - "integrity": "sha512-KWBIxs1Xb6NoLdMVqhbhgwZf2PGBpPEiwOqgI4pFIYbNTfBXiKYyWoTsXgBQ9WFg/OlhnvHaY+AEpW7wSmFo2Q==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.3.0.tgz", + "integrity": "sha512-y6nxMGB1nMW9R6k96e5gdIFzcfL/gTJRNaqGes1YvkLnPVXzWgbqFF2yLC0T8G774n24cx3Pe8XrKoniCOAH+Q==", "license": "MIT" }, "node_modules/tapable": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.2.tgz", - "integrity": "sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz", + "integrity": "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==", "license": "MIT", "engines": { "node": ">=6" diff --git a/src/styling/src/package.json b/src/styling/src/package.json index 5acf123ef..7a25bdcf0 100644 --- a/src/styling/src/package.json +++ b/src/styling/src/package.json @@ -1,10 +1,10 @@ { "scripts": { - "build:css": "npx @tailwindcss/cli -i ./wwwroot/tailwindroot.css -o ./wwwroot/css/axopenstyling.css --minify", - "watch:css": "npx @tailwindcss/cli -i ./wwwroot/tailwindroot.css -o ./wwwroot/css/axopenstyling.css --watch" + "build:css": "npx @tailwindcss/cli -i ./wwwroot/css/tailwind.css -o ./wwwroot/css/momentum.css --minify --content \"..\\..\\..\\**\\*.{html,js,jsx,ts,tsx,vue,razor}\"", + "watch:css": "npx @tailwindcss/cli -i ./wwwroot/css/tailwind.css -o ./wwwroot/css/momentum.css --watch --content \"..\\..\\..\\**\\*.{html,js,jsx,ts,tsx,vue,razor}\"" }, "dependencies": { - "@tailwindcss/cli": "^4.2.2", - "tailwindcss": "^4.2.2" + "@tailwindcss/cli": "^4.3.0", + "tailwindcss": "^4.3.0" } } diff --git a/src/styling/src/wwwroot/css/momentum.css b/src/styling/src/wwwroot/css/momentum.css index 1ca14ac2b..4ac1215be 100644 --- a/src/styling/src/wwwroot/css/momentum.css +++ b/src/styling/src/wwwroot/css/momentum.css @@ -1,2 +1,2 @@ -/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */ -@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-space-x-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial;--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0}}}@layer theme{:root,:host{--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-orange-50:oklch(98% .016 73.684);--color-orange-200:oklch(90.1% .076 70.697);--color-orange-400:oklch(75% .183 55.934);--color-orange-500:oklch(70.5% .213 47.604);--color-orange-600:oklch(64.6% .222 41.116);--color-orange-700:oklch(55.3% .195 38.402);--color-amber-50:oklch(98.7% .022 95.277);--color-amber-400:oklch(82.8% .189 84.429);--color-amber-600:oklch(66.6% .179 58.318);--color-amber-700:oklch(55.5% .163 48.998);--color-yellow-400:oklch(85.2% .199 91.936);--color-yellow-500:oklch(79.5% .184 86.047);--color-lime-400:oklch(84.1% .238 128.85);--color-green-500:oklch(72.3% .219 149.579);--color-emerald-50:oklch(97.9% .021 166.113);--color-emerald-500:oklch(69.6% .17 162.48);--color-emerald-700:oklch(50.8% .118 165.612);--color-cyan-50:oklch(98.4% .019 200.873);--color-cyan-100:oklch(95.6% .045 203.388);--color-cyan-200:oklch(91.7% .08 205.041);--color-cyan-400:oklch(78.9% .154 211.53);--color-cyan-500:oklch(71.5% .143 215.221);--color-cyan-700:oklch(52% .105 223.128);--color-cyan-900:oklch(39.8% .07 227.392);--color-sky-400:oklch(74.6% .16 232.661);--color-blue-500:oklch(62.3% .214 259.815);--color-purple-500:oklch(62.7% .265 303.9);--color-slate-50:oklch(98.4% .003 247.858);--color-slate-100:oklch(96.8% .007 247.896);--color-slate-200:oklch(92.9% .013 255.508);--color-slate-300:oklch(86.9% .022 252.894);--color-slate-400:oklch(70.4% .04 256.788);--color-slate-500:oklch(55.4% .046 257.417);--color-slate-600:oklch(44.6% .043 257.281);--color-slate-700:oklch(37.2% .044 257.287);--color-slate-800:oklch(27.9% .041 260.031);--color-slate-900:oklch(20.8% .042 265.755);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-700:oklch(37.3% .034 259.733);--color-gray-900:oklch(21% .034 264.665);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-xs:20rem;--container-md:28rem;--container-xl:36rem;--container-3xl:48rem;--container-4xl:56rem;--container-7xl:80rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25 / 1.875);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-wide:.025em;--tracking-wider:.05em;--tracking-widest:.1em;--leading-tight:1.25;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--ease-in-out:cubic-bezier(.4, 0, .2, 1);--animate-spin:spin 1s linear infinite;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--animate-bounce:bounce 1s infinite;--blur-sm:8px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1)}}@layer base,components;@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{inset:calc(var(--spacing) * 0)}.start{inset-inline-start:var(--spacing)}.end{inset-inline-end:var(--spacing)}.top-2{top:calc(var(--spacing) * 2)}.right-2{right:calc(var(--spacing) * 2)}.bottom-0{bottom:calc(var(--spacing) * 0)}.-z-1{z-index:calc(1 * -1)}.z-10{z-index:10}.z-\[600\]{z-index:600}.col-span-2{grid-column:span 2/span 2}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.\!m-0{margin:calc(var(--spacing) * 0)!important}.m-0{margin:calc(var(--spacing) * 0)}.m-0\!{margin:calc(var(--spacing) * 0)!important}.m-1{margin:calc(var(--spacing) * 1)}.m-2{margin:calc(var(--spacing) * 2)}.m-4{margin:calc(var(--spacing) * 4)}.-mx-2{margin-inline:calc(var(--spacing) * -2)}.mx-2{margin-inline:calc(var(--spacing) * 2)}.mx-4{margin-inline:calc(var(--spacing) * 4)}.mx-auto{margin-inline:auto}.my-1{margin-block:calc(var(--spacing) * 1)}.my-2{margin-block:calc(var(--spacing) * 2)}.my-3{margin-block:calc(var(--spacing) * 3)}.my-4{margin-block:calc(var(--spacing) * 4)}.my-auto{margin-block:auto}.ms-1{margin-inline-start:calc(var(--spacing) * 1)}.ms-2{margin-inline-start:calc(var(--spacing) * 2)}.ms-4{margin-inline-start:calc(var(--spacing) * 4)}.ms-auto{margin-inline-start:auto}.me-1{margin-inline-end:calc(var(--spacing) * 1)}.me-2{margin-inline-end:calc(var(--spacing) * 2)}.me-4{margin-inline-end:calc(var(--spacing) * 4)}.me-6{margin-inline-end:calc(var(--spacing) * 6)}.me-auto{margin-inline-end:auto}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-\[15vh\]{margin-top:15vh}.mt-auto{margin-top:auto}.mr-1{margin-right:calc(var(--spacing) * 1)}.mr-2{margin-right:calc(var(--spacing) * 2)}.mb-0{margin-bottom:calc(var(--spacing) * 0)}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.mb-6{margin-bottom:calc(var(--spacing) * 6)}.ml-1{margin-left:calc(var(--spacing) * 1)}.ml-4{margin-left:calc(var(--spacing) * 4)}.ml-5{margin-left:calc(var(--spacing) * 5)}.ml-auto{margin-left:auto}.line-clamp-1{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.line-clamp-2{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.contents{display:contents}.flex{display:flex}.flex\!{display:flex!important}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-flex{display:inline-flex}.table{display:table}.size-3{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.size-5{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.size-6{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6)}.size-7{width:calc(var(--spacing) * 7);height:calc(var(--spacing) * 7)}.size-16{width:calc(var(--spacing) * 16);height:calc(var(--spacing) * 16)}.h-2{height:calc(var(--spacing) * 2)}.h-3{height:calc(var(--spacing) * 3)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-8{height:calc(var(--spacing) * 8)}.h-11{height:calc(var(--spacing) * 11)}.h-12{height:calc(var(--spacing) * 12)}.h-15{height:calc(var(--spacing) * 15)}.h-auto{height:auto}.h-full{height:100%}.max-h-\[50vh\]{max-height:50vh}.max-h-\[70vh\]{max-height:70vh}.min-h-40{min-height:calc(var(--spacing) * 40)}.w-1\/3{width:33.3333%}.w-2{width:calc(var(--spacing) * 2)}.w-3{width:calc(var(--spacing) * 3)}.w-5{width:calc(var(--spacing) * 5)}.w-6{width:calc(var(--spacing) * 6)}.w-8{width:calc(var(--spacing) * 8)}.w-15{width:calc(var(--spacing) * 15)}.w-16{width:calc(var(--spacing) * 16)}.w-20{width:calc(var(--spacing) * 20)}.w-50{width:calc(var(--spacing) * 50)}.w-75{width:calc(var(--spacing) * 75)}.w-100{width:calc(var(--spacing) * 100)}.w-125{width:calc(var(--spacing) * 125)}.w-\[1px\]{width:1px}.w-auto{width:auto}.w-full{width:100%}.w-md{width:var(--container-md)}.max-w-3xl{max-width:var(--container-3xl)}.max-w-4xl{max-width:var(--container-4xl)}.max-w-7xl{max-width:var(--container-7xl)}.max-w-200{max-width:calc(var(--spacing) * 200)}.max-w-none{max-width:none}.max-w-xl{max-width:var(--container-xl)}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:calc(var(--spacing) * 0)}.min-w-6{min-width:calc(var(--spacing) * 6)}.min-w-20{min-width:calc(var(--spacing) * 20)}.min-w-32{min-width:calc(var(--spacing) * 32)}.min-w-\[10rem\]{min-width:10rem}.min-w-\[12rem\]{min-width:12rem}.flex-1{flex:1}.flex-\[2\]{flex:2}.flex-shrink-0,.shrink-0{flex-shrink:0}.flex-grow-1,.grow,.grow-1{flex-grow:1}.basis-1\/3{flex-basis:33.3333%}.basis-2\/3{flex-basis:66.6667%}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-bounce{animation:var(--animate-bounce)}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.cursor-default{cursor:default}.cursor-move{cursor:move}.cursor-pointer{cursor:pointer}.list-inside{list-style-position:inside}.list-disc{list-style-type:disc}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-row{flex-direction:row}.flex-row\!{flex-direction:row!important}.flex-nowrap{flex-wrap:nowrap}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-center\!{align-items:center!important}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-0{gap:calc(var(--spacing) * 0)}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-6{gap:calc(var(--spacing) * 6)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 6) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 6) * calc(1 - var(--tw-space-y-reverse)))}.gap-x-6{column-gap:calc(var(--spacing) * 6)}:where(.space-x-4>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing) * 4) * var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-x-reverse)))}.gap-y-1{row-gap:calc(var(--spacing) * 1)}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-slate-100>:not(:last-child)){border-color:var(--color-slate-100)}.self-center{align-self:center}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.overflow-y-visible{overflow-y:visible}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-xl{border-radius:var(--radius-xl)}.rounded-t{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.rounded-l-md{border-top-left-radius:var(--radius-md);border-bottom-left-radius:var(--radius-md)}.rounded-r-md{border-top-right-radius:var(--radius-md);border-bottom-right-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-t-2{border-top-style:var(--tw-border-style);border-top-width:2px}.border-b,.border-b-1{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-solid{--tw-border-style:solid;border-style:solid}.border-blue-500\/50{border-color:#3080ff80}@supports (color:color-mix(in lab, red, red)){.border-blue-500\/50{border-color:color-mix(in oklab, var(--color-blue-500) 50%, transparent)}}.border-current{border-color:currentColor}.border-cyan-200{border-color:var(--color-cyan-200)}.border-cyan-400{border-color:var(--color-cyan-400)}.border-green-500\/50{border-color:#00c75880}@supports (color:color-mix(in lab, red, red)){.border-green-500\/50{border-color:color-mix(in oklab, var(--color-green-500) 50%, transparent)}}.border-orange-200{border-color:var(--color-orange-200)}.border-orange-400\/50{border-color:#ff8b1a80}@supports (color:color-mix(in lab, red, red)){.border-orange-400\/50{border-color:color-mix(in oklab, var(--color-orange-400) 50%, transparent)}}.border-red-500\/50{border-color:#fb2c3680}@supports (color:color-mix(in lab, red, red)){.border-red-500\/50{border-color:color-mix(in oklab, var(--color-red-500) 50%, transparent)}}.border-slate-100{border-color:var(--color-slate-100)}.border-slate-200{border-color:var(--color-slate-200)}.border-slate-300{border-color:var(--color-slate-300)}.border-slate-400\/35{border-color:#90a1b959}@supports (color:color-mix(in lab, red, red)){.border-slate-400\/35{border-color:color-mix(in oklab, var(--color-slate-400) 35%, transparent)}}.border-slate-500\/40{border-color:#62748e66}@supports (color:color-mix(in lab, red, red)){.border-slate-500\/40{border-color:color-mix(in oklab, var(--color-slate-500) 40%, transparent)}}.border-yellow-500\/50{border-color:#edb20080}@supports (color:color-mix(in lab, red, red)){.border-yellow-500\/50{border-color:color-mix(in oklab, var(--color-yellow-500) 50%, transparent)}}.bg-amber-50{background-color:var(--color-amber-50)}.bg-black\/50{background-color:#00000080}@supports (color:color-mix(in lab, red, red)){.bg-black\/50{background-color:color-mix(in oklab, var(--color-black) 50%, transparent)}}.bg-blue-500{background-color:var(--color-blue-500)}.bg-current{background-color:currentColor}.bg-cyan-50{background-color:var(--color-cyan-50)}.bg-cyan-100\/40{background-color:#cefafe66}@supports (color:color-mix(in lab, red, red)){.bg-cyan-100\/40{background-color:color-mix(in oklab, var(--color-cyan-100) 40%, transparent)}}.bg-cyan-500{background-color:var(--color-cyan-500)}.bg-gray-700{background-color:var(--color-gray-700)}.bg-green-500{background-color:var(--color-green-500)}.bg-orange-50{background-color:var(--color-orange-50)}.bg-red-500{background-color:var(--color-red-500)}.bg-slate-50{background-color:var(--color-slate-50)}.bg-slate-100{background-color:var(--color-slate-100)}.bg-slate-200{background-color:var(--color-slate-200)}.bg-slate-400\/20{background-color:#90a1b933}@supports (color:color-mix(in lab, red, red)){.bg-slate-400\/20{background-color:color-mix(in oklab, var(--color-slate-400) 20%, transparent)}}.bg-slate-500{background-color:var(--color-slate-500)}.bg-slate-700{background-color:var(--color-slate-700)}.bg-slate-700\/40{background-color:#31415866}@supports (color:color-mix(in lab, red, red)){.bg-slate-700\/40{background-color:color-mix(in oklab, var(--color-slate-700) 40%, transparent)}}.bg-slate-800\/60{background-color:#1d293d99}@supports (color:color-mix(in lab, red, red)){.bg-slate-800\/60{background-color:color-mix(in oklab, var(--color-slate-800) 60%, transparent)}}.bg-slate-900\/35{background-color:#0f172b59}@supports (color:color-mix(in lab, red, red)){.bg-slate-900\/35{background-color:color-mix(in oklab, var(--color-slate-900) 35%, transparent)}}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.bg-white\/60{background-color:#fff9}@supports (color:color-mix(in lab, red, red)){.bg-white\/60{background-color:color-mix(in oklab, var(--color-white) 60%, transparent)}}.bg-white\/80{background-color:#fffc}@supports (color:color-mix(in lab, red, red)){.bg-white\/80{background-color:color-mix(in oklab, var(--color-white) 80%, transparent)}}.bg-yellow-400{background-color:var(--color-yellow-400)}.bg-yellow-500{background-color:var(--color-yellow-500)}.bg-linear-to-br{--tw-gradient-position:to bottom right}@supports (background-image:linear-gradient(in lab, red, red)){.bg-linear-to-br{--tw-gradient-position:to bottom right in oklab}}.bg-linear-to-br{background-image:linear-gradient(var(--tw-gradient-stops))}.bg-linear-to-r{--tw-gradient-position:to right}@supports (background-image:linear-gradient(in lab, red, red)){.bg-linear-to-r{--tw-gradient-position:to right in oklab}}.bg-linear-to-r{background-image:linear-gradient(var(--tw-gradient-stops))}.bg-gradient-to-r{--tw-gradient-position:to right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.from-cyan-50{--tw-gradient-from:var(--color-cyan-50);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.from-emerald-50{--tw-gradient-from:var(--color-emerald-50);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.from-green-500{--tw-gradient-from:var(--color-green-500);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.from-red-500{--tw-gradient-from:var(--color-red-500);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.from-yellow-400{--tw-gradient-from:var(--color-yellow-400);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.from-0\%{--tw-gradient-from-position:0%}.via-amber-400{--tw-gradient-via:var(--color-amber-400);--tw-gradient-via-stops:var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.via-cyan-500{--tw-gradient-via:var(--color-cyan-500);--tw-gradient-via-stops:var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.via-lime-400{--tw-gradient-via:var(--color-lime-400);--tw-gradient-via-stops:var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.via-purple-500{--tw-gradient-via:var(--color-purple-500);--tw-gradient-via-stops:var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.via-sky-400{--tw-gradient-via:var(--color-sky-400);--tw-gradient-via-stops:var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.via-yellow-400{--tw-gradient-via:var(--color-yellow-400);--tw-gradient-via-stops:var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.to-blue-500{--tw-gradient-to:var(--color-blue-500);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.to-green-500{--tw-gradient-to:var(--color-green-500);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.to-white{--tw-gradient-to:var(--color-white);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.to-50\%{--tw-gradient-to-position:50%}.\!p-0{padding:calc(var(--spacing) * 0)!important}.p-0{padding:calc(var(--spacing) * 0)}.p-0\!{padding:calc(var(--spacing) * 0)!important}.p-1{padding:calc(var(--spacing) * 1)}.p-1\.5{padding:calc(var(--spacing) * 1.5)}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-6{padding:calc(var(--spacing) * 6)}.p-10{padding:calc(var(--spacing) * 10)}.px-1{padding-inline:calc(var(--spacing) * 1)}.px-1\!{padding-inline:calc(var(--spacing) * 1)!important}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\!{padding-inline:calc(var(--spacing) * 2)!important}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-3\.5{padding-inline:calc(var(--spacing) * 3.5)}.px-4{padding-inline:calc(var(--spacing) * 4)}.py-0{padding-block:calc(var(--spacing) * 0)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-1\!{padding-block:calc(var(--spacing) * 1)!important}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\!{padding-block:calc(var(--spacing) * 2)!important}.py-3{padding-block:calc(var(--spacing) * 3)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-8{padding-block:calc(var(--spacing) * 8)}.ps-3{padding-inline-start:calc(var(--spacing) * 3)}.pt-1{padding-top:calc(var(--spacing) * 1)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-3{padding-top:calc(var(--spacing) * 3)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pb-1{padding-bottom:calc(var(--spacing) * 1)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pl-2{padding-left:calc(var(--spacing) * 2)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.text-start{text-align:start}.align-middle{vertical-align:middle}.font-mono{font-family:var(--font-mono)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[0\.8rem\]{font-size:.8rem}.text-\[0\.65rem\]{font-size:.65rem}.text-\[0\.85rem\]{font-size:.85rem}.text-\[0\.95rem\]{font-size:.95rem}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.tracking-widest{--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest)}.text-balance{text-wrap:balance}.text-nowrap{text-wrap:nowrap}.wrap-anywhere{overflow-wrap:anywhere}.whitespace-nowrap{white-space:nowrap}.text-amber-400{color:var(--color-amber-400)}.text-amber-600\/80{color:#dd7400cc}@supports (color:color-mix(in lab, red, red)){.text-amber-600\/80{color:color-mix(in oklab, var(--color-amber-600) 80%, transparent)}}.text-amber-700{color:var(--color-amber-700)}.text-blue-500{color:var(--color-blue-500)}.text-cyan-700{color:var(--color-cyan-700)}.text-cyan-900{color:var(--color-cyan-900)}.text-emerald-500{color:var(--color-emerald-500)}.text-emerald-700{color:var(--color-emerald-700)}.text-gray-100{color:var(--color-gray-100)}.text-gray-900{color:var(--color-gray-900)}.text-green-500{color:var(--color-green-500)}.text-inherit{color:inherit}.text-inherit\!{color:inherit!important}.text-orange-500{color:var(--color-orange-500)}.text-orange-600{color:var(--color-orange-600)}.text-orange-700{color:var(--color-orange-700)}.text-red-400{color:var(--color-red-400)}.text-red-500{color:var(--color-red-500)}.text-slate-100\/95{color:#f1f5f9f2}@supports (color:color-mix(in lab, red, red)){.text-slate-100\/95{color:color-mix(in oklab, var(--color-slate-100) 95%, transparent)}}.text-slate-200{color:var(--color-slate-200)}.text-slate-300{color:var(--color-slate-300)}.text-slate-400{color:var(--color-slate-400)}.text-slate-400\/90{color:#90a1b9e6}@supports (color:color-mix(in lab, red, red)){.text-slate-400\/90{color:color-mix(in oklab, var(--color-slate-400) 90%, transparent)}}.text-slate-500{color:var(--color-slate-500)}.text-slate-600{color:var(--color-slate-600)}.text-slate-700{color:var(--color-slate-700)}.text-slate-800{color:var(--color-slate-800)}.text-slate-900{color:var(--color-slate-900)}.text-slate-900\/70{color:#0f172bb3}@supports (color:color-mix(in lab, red, red)){.text-slate-900\/70{color:color-mix(in oklab, var(--color-slate-900) 70%, transparent)}}.text-slate-900\/85{color:#0f172bd9}@supports (color:color-mix(in lab, red, red)){.text-slate-900\/85{color:color-mix(in oklab, var(--color-slate-900) 85%, transparent)}}.text-slate-900\/90{color:#0f172be6}@supports (color:color-mix(in lab, red, red)){.text-slate-900\/90{color:color-mix(in oklab, var(--color-slate-900) 90%, transparent)}}.text-white{color:var(--color-white)}.text-yellow-500{color:var(--color-yellow-500)}.uppercase{text-transform:uppercase}.ordinal{--tw-ordinal:ordinal;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.placeholder-slate-400::placeholder{color:var(--color-slate-400)}.opacity-0{opacity:0}.opacity-25{opacity:.25}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-75{opacity:.75}.opacity-90{opacity:.9}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_0_8px_rgba\(34\,197\,94\,0\.6\)\]{--tw-shadow:0 0 8px var(--tw-shadow-color,#22c55e99);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-blue-500\/50{--tw-shadow-color:#3080ff80}@supports (color:color-mix(in lab, red, red)){.shadow-blue-500\/50{--tw-shadow-color:color-mix(in oklab, color-mix(in oklab, var(--color-blue-500) 50%, transparent) var(--tw-shadow-alpha), transparent)}}.shadow-green-500\/50{--tw-shadow-color:#00c75880}@supports (color:color-mix(in lab, red, red)){.shadow-green-500\/50{--tw-shadow-color:color-mix(in oklab, color-mix(in oklab, var(--color-green-500) 50%, transparent) var(--tw-shadow-alpha), transparent)}}.shadow-orange-400\/40{--tw-shadow-color:#ff8b1a66}@supports (color:color-mix(in lab, red, red)){.shadow-orange-400\/40{--tw-shadow-color:color-mix(in oklab, color-mix(in oklab, var(--color-orange-400) 40%, transparent) var(--tw-shadow-alpha), transparent)}}.shadow-red-500\/50{--tw-shadow-color:#fb2c3680}@supports (color:color-mix(in lab, red, red)){.shadow-red-500\/50{--tw-shadow-color:color-mix(in oklab, color-mix(in oklab, var(--color-red-500) 50%, transparent) var(--tw-shadow-alpha), transparent)}}.shadow-yellow-500\/50{--tw-shadow-color:#edb20080}@supports (color:color-mix(in lab, red, red)){.shadow-yellow-500\/50{--tw-shadow-color:color-mix(in oklab, color-mix(in oklab, var(--color-yellow-500) 50%, transparent) var(--tw-shadow-alpha), transparent)}}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.backdrop-blur-sm{--tw-backdrop-blur:blur(var(--blur-sm));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.duration-400{--tw-duration:.4s;transition-duration:.4s}.duration-500{--tw-duration:.5s;transition-duration:.5s}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.\[assembly\:InternalsVisibleTo\(\"axopen\.inspectors_tests\"\)\]{assembly:InternalsVisibleTo("axopen.inspectors tests")}.\[assembly\:InternalsVisibleTo\(\"axopen_core_tests\"\)\]{assembly:InternalsVisibleTo("axopen core tests")}.\[assembly\:InternalsVisibleTo\(\"axopen_core_tests_L1\"\)\]{assembly:InternalsVisibleTo("axopen core tests L1")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentsabbrobotics_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentsabbrobotics tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentsballuffidentification_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentsballuffidentification tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentscognexvision_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentscognexvision tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentsdesouttertightening_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentsdesouttertightening tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentsdrives_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentsdrives tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentsfestodrives_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentsfestodrives tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentskeyencevision_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentskeyencevision tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentskukarobotics_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentskukarobotics tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentsmitsubishirobotics_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentsmitsubishirobotics tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentsrexrothdrives_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentsrexrothdrives tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentsrexrothpress_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentsrexrothpress tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentsrobotics_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentsrobotics tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentssiemidentification_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentssiemidentification tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentsurrobotics_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentsurrobotics tests")}.\[assembly\:InternalsVisibleTo\(\"axopenio_tests\"\)\]{assembly:InternalsVisibleTo("axopenio tests")}.\[assembly\:InternalsVisibleTo\(\"components\.dukane\.welders_tests\"\)\]{assembly:InternalsVisibleTo("components.dukane.welders tests")}.\[assembly\:InternalsVisibleTo\(\"components\.rexroth\.tightening_tests\"\)\]{assembly:InternalsVisibleTo("components.rexroth.tightening tests")}.\[assembly\:InternalsVisibleTo\(\"components\.siem\.communication_tests\"\)\]{assembly:InternalsVisibleTo("components.siem.communication tests")}.\[assembly\:InternalsVisibleTo\(\"components\.zebra\.vision_tests\"\)\]{assembly:InternalsVisibleTo("components.zebra.vision tests")}.\[assembly\:InternalsVisibleTo\(\"elementscomponents_tests\"\)\]{assembly:InternalsVisibleTo("elementscomponents tests")}.\[assembly\:InternalsVisibleTo\(\"librarytemplate_tests\"\)\]{assembly:InternalsVisibleTo("librarytemplate tests")}.\[assembly\:InternalsVisibleTo\(\"pneumaticcomponents_tests\"\)\]{assembly:InternalsVisibleTo("pneumaticcomponents tests")}@media (hover:hover){.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}.hover\:-translate-y-0\.5:hover{--tw-translate-y:calc(var(--spacing) * -.5);translate:var(--tw-translate-x) var(--tw-translate-y)}.hover\:border-slate-300:hover{border-color:var(--color-slate-300)}.hover\:bg-slate-50:hover{background-color:var(--color-slate-50)}.hover\:bg-slate-600:hover{background-color:var(--color-slate-600)}.hover\:text-slate-700:hover{color:var(--color-slate-700)}.hover\:text-slate-800:hover{color:var(--color-slate-800)}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-100:hover{opacity:1}.hover\:shadow-lg:hover{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}}.focus\:border-cyan-500:focus{border-color:var(--color-cyan-500)}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus\:ring-cyan-200:focus{--tw-ring-color:var(--color-cyan-200)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}@media (min-width:40rem){.sm\:inline{display:inline}.sm\:px-6{padding-inline:calc(var(--spacing) * 6)}}@media (min-width:48rem){.md\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:grid-rows-2{grid-template-rows:repeat(2,minmax(0,1fr))}.md\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}@media (min-width:64rem){.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.lg\:flex-row{flex-direction:row}.lg\:items-center{align-items:center}.lg\:justify-between{justify-content:space-between}.lg\:px-8{padding-inline:calc(var(--spacing) * 8)}}@media (min-width:80rem){.xl\:col-span-1{grid-column:span 1/span 1}.xl\:col-span-2{grid-column:span 2/span 2}.xl\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-space-x-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"";inherits:false;initial-value:100%}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}@keyframes bounce{0%,to{animation-timing-function:cubic-bezier(.8,0,1,1);transform:translateY(-25%)}50%{animation-timing-function:cubic-bezier(0,0,.2,1);transform:none}} \ No newline at end of file +/*! tailwindcss v4.3.0 | MIT License | https://tailwindcss.com */ +@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-space-x-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial;--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0}}}@layer theme{:root,:host{--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-orange-50:oklch(98% .016 73.684);--color-orange-200:oklch(90.1% .076 70.697);--color-orange-400:oklch(75% .183 55.934);--color-orange-500:oklch(70.5% .213 47.604);--color-orange-600:oklch(64.6% .222 41.116);--color-orange-700:oklch(55.3% .195 38.402);--color-amber-50:oklch(98.7% .022 95.277);--color-amber-400:oklch(82.8% .189 84.429);--color-amber-600:oklch(66.6% .179 58.318);--color-amber-700:oklch(55.5% .163 48.998);--color-yellow-400:oklch(85.2% .199 91.936);--color-yellow-500:oklch(79.5% .184 86.047);--color-lime-400:oklch(84.1% .238 128.85);--color-green-500:oklch(72.3% .219 149.579);--color-emerald-50:oklch(97.9% .021 166.113);--color-emerald-500:oklch(69.6% .17 162.48);--color-emerald-700:oklch(50.8% .118 165.612);--color-cyan-50:oklch(98.4% .019 200.873);--color-cyan-100:oklch(95.6% .045 203.388);--color-cyan-200:oklch(91.7% .08 205.041);--color-cyan-400:oklch(78.9% .154 211.53);--color-cyan-500:oklch(71.5% .143 215.221);--color-cyan-700:oklch(52% .105 223.128);--color-cyan-900:oklch(39.8% .07 227.392);--color-sky-400:oklch(74.6% .16 232.661);--color-blue-500:oklch(62.3% .214 259.815);--color-purple-500:oklch(62.7% .265 303.9);--color-slate-50:oklch(98.4% .003 247.858);--color-slate-100:oklch(96.8% .007 247.896);--color-slate-200:oklch(92.9% .013 255.508);--color-slate-300:oklch(86.9% .022 252.894);--color-slate-400:oklch(70.4% .04 256.788);--color-slate-500:oklch(55.4% .046 257.417);--color-slate-600:oklch(44.6% .043 257.281);--color-slate-700:oklch(37.2% .044 257.287);--color-slate-800:oklch(27.9% .041 260.031);--color-slate-900:oklch(20.8% .042 265.755);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-700:oklch(37.3% .034 259.733);--color-gray-900:oklch(21% .034 264.665);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-xs:20rem;--container-md:28rem;--container-xl:36rem;--container-3xl:48rem;--container-4xl:56rem;--container-7xl:80rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25 / 1.875);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-wide:.025em;--tracking-wider:.05em;--tracking-widest:.1em;--leading-tight:1.25;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--ease-in-out:cubic-bezier(.4, 0, .2, 1);--animate-spin:spin 1s linear infinite;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--animate-bounce:bounce 1s infinite;--blur-sm:8px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1)}}@layer base,components;@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{inset:calc(var(--spacing) * 0)}.top-2{top:calc(var(--spacing) * 2)}.right-2{right:calc(var(--spacing) * 2)}.bottom-0{bottom:calc(var(--spacing) * 0)}.-z-1{z-index:calc(1 * -1)}.z-10{z-index:10}.z-\[600\]{z-index:600}.col-span-2{grid-column:span 2/span 2}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.\!m-0{margin:calc(var(--spacing) * 0)!important}.m-0{margin:calc(var(--spacing) * 0)}.m-0\!{margin:calc(var(--spacing) * 0)!important}.m-1{margin:calc(var(--spacing) * 1)}.m-2{margin:calc(var(--spacing) * 2)}.m-4{margin:calc(var(--spacing) * 4)}.-mx-2{margin-inline:calc(var(--spacing) * -2)}.mx-2{margin-inline:calc(var(--spacing) * 2)}.mx-4{margin-inline:calc(var(--spacing) * 4)}.mx-auto{margin-inline:auto}.my-1{margin-block:calc(var(--spacing) * 1)}.my-2{margin-block:calc(var(--spacing) * 2)}.my-3{margin-block:calc(var(--spacing) * 3)}.my-4{margin-block:calc(var(--spacing) * 4)}.my-auto{margin-block:auto}.ms-1{margin-inline-start:calc(var(--spacing) * 1)}.ms-2{margin-inline-start:calc(var(--spacing) * 2)}.ms-4{margin-inline-start:calc(var(--spacing) * 4)}.ms-auto{margin-inline-start:auto}.me-1{margin-inline-end:calc(var(--spacing) * 1)}.me-2{margin-inline-end:calc(var(--spacing) * 2)}.me-4{margin-inline-end:calc(var(--spacing) * 4)}.me-6{margin-inline-end:calc(var(--spacing) * 6)}.me-auto{margin-inline-end:auto}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-\[15vh\]{margin-top:15vh}.mt-auto{margin-top:auto}.mr-1{margin-right:calc(var(--spacing) * 1)}.mr-2{margin-right:calc(var(--spacing) * 2)}.mb-0{margin-bottom:calc(var(--spacing) * 0)}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.mb-6{margin-bottom:calc(var(--spacing) * 6)}.ml-1{margin-left:calc(var(--spacing) * 1)}.ml-4{margin-left:calc(var(--spacing) * 4)}.ml-5{margin-left:calc(var(--spacing) * 5)}.ml-auto{margin-left:auto}.line-clamp-1{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.line-clamp-2{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.contents{display:contents}.flex{display:flex}.flex\!{display:flex!important}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-flex{display:inline-flex}.table{display:table}.size-3{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.size-5{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.size-6{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6)}.size-7{width:calc(var(--spacing) * 7);height:calc(var(--spacing) * 7)}.size-16{width:calc(var(--spacing) * 16);height:calc(var(--spacing) * 16)}.h-2{height:calc(var(--spacing) * 2)}.h-3{height:calc(var(--spacing) * 3)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-8{height:calc(var(--spacing) * 8)}.h-11{height:calc(var(--spacing) * 11)}.h-12{height:calc(var(--spacing) * 12)}.h-15{height:calc(var(--spacing) * 15)}.h-auto{height:auto}.h-full{height:100%}.max-h-\[50vh\]{max-height:50vh}.max-h-\[70vh\]{max-height:70vh}.min-h-40{min-height:calc(var(--spacing) * 40)}.w-1\/3{width:33.3333%}.w-2{width:calc(var(--spacing) * 2)}.w-3{width:calc(var(--spacing) * 3)}.w-5{width:calc(var(--spacing) * 5)}.w-6{width:calc(var(--spacing) * 6)}.w-8{width:calc(var(--spacing) * 8)}.w-15{width:calc(var(--spacing) * 15)}.w-16{width:calc(var(--spacing) * 16)}.w-20{width:calc(var(--spacing) * 20)}.w-50{width:calc(var(--spacing) * 50)}.w-75{width:calc(var(--spacing) * 75)}.w-100{width:calc(var(--spacing) * 100)}.w-125{width:calc(var(--spacing) * 125)}.w-\[1px\]{width:1px}.w-auto{width:auto}.w-full{width:100%}.w-md{width:var(--container-md)}.max-w-3xl{max-width:var(--container-3xl)}.max-w-4xl{max-width:var(--container-4xl)}.max-w-7xl{max-width:var(--container-7xl)}.max-w-200{max-width:calc(var(--spacing) * 200)}.max-w-none{max-width:none}.max-w-xl{max-width:var(--container-xl)}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:calc(var(--spacing) * 0)}.min-w-6{min-width:calc(var(--spacing) * 6)}.min-w-20{min-width:calc(var(--spacing) * 20)}.min-w-32{min-width:calc(var(--spacing) * 32)}.min-w-\[10rem\]{min-width:10rem}.min-w-\[12rem\]{min-width:12rem}.flex-1{flex:1}.flex-\[2\]{flex:2}.flex-shrink-0,.shrink-0{flex-shrink:0}.flex-grow-1,.grow,.grow-1{flex-grow:1}.basis-1\/3{flex-basis:33.3333%}.basis-2\/3{flex-basis:66.6667%}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-bounce{animation:var(--animate-bounce)}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.cursor-default{cursor:default}.cursor-move{cursor:move}.cursor-pointer{cursor:pointer}.list-inside{list-style-position:inside}.list-disc{list-style-type:disc}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-row{flex-direction:row}.flex-row\!{flex-direction:row!important}.flex-nowrap{flex-wrap:nowrap}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-center\!{align-items:center!important}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-0{gap:calc(var(--spacing) * 0)}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-6{gap:calc(var(--spacing) * 6)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 6) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 6) * calc(1 - var(--tw-space-y-reverse)))}.gap-x-6{column-gap:calc(var(--spacing) * 6)}:where(.space-x-4>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing) * 4) * var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-x-reverse)))}.gap-y-1{row-gap:calc(var(--spacing) * 1)}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-slate-100>:not(:last-child)){border-color:var(--color-slate-100)}.self-center{align-self:center}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.overflow-y-visible{overflow-y:visible}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-xl{border-radius:var(--radius-xl)}.rounded-t{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.rounded-l-md{border-top-left-radius:var(--radius-md);border-bottom-left-radius:var(--radius-md)}.rounded-r-md{border-top-right-radius:var(--radius-md);border-bottom-right-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-t-2{border-top-style:var(--tw-border-style);border-top-width:2px}.border-b,.border-b-1{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-solid{--tw-border-style:solid;border-style:solid}.border-blue-500\/50{border-color:#3080ff80}@supports (color:color-mix(in lab, red, red)){.border-blue-500\/50{border-color:color-mix(in oklab, var(--color-blue-500) 50%, transparent)}}.border-current{border-color:currentColor}.border-cyan-200{border-color:var(--color-cyan-200)}.border-cyan-400{border-color:var(--color-cyan-400)}.border-green-500\/50{border-color:#00c75880}@supports (color:color-mix(in lab, red, red)){.border-green-500\/50{border-color:color-mix(in oklab, var(--color-green-500) 50%, transparent)}}.border-orange-200{border-color:var(--color-orange-200)}.border-orange-400\/50{border-color:#ff8b1a80}@supports (color:color-mix(in lab, red, red)){.border-orange-400\/50{border-color:color-mix(in oklab, var(--color-orange-400) 50%, transparent)}}.border-red-500\/50{border-color:#fb2c3680}@supports (color:color-mix(in lab, red, red)){.border-red-500\/50{border-color:color-mix(in oklab, var(--color-red-500) 50%, transparent)}}.border-slate-100{border-color:var(--color-slate-100)}.border-slate-200{border-color:var(--color-slate-200)}.border-slate-300{border-color:var(--color-slate-300)}.border-slate-400\/35{border-color:#90a1b959}@supports (color:color-mix(in lab, red, red)){.border-slate-400\/35{border-color:color-mix(in oklab, var(--color-slate-400) 35%, transparent)}}.border-slate-500\/40{border-color:#62748e66}@supports (color:color-mix(in lab, red, red)){.border-slate-500\/40{border-color:color-mix(in oklab, var(--color-slate-500) 40%, transparent)}}.border-yellow-500\/50{border-color:#edb20080}@supports (color:color-mix(in lab, red, red)){.border-yellow-500\/50{border-color:color-mix(in oklab, var(--color-yellow-500) 50%, transparent)}}.bg-amber-50{background-color:var(--color-amber-50)}.bg-black\/50{background-color:#00000080}@supports (color:color-mix(in lab, red, red)){.bg-black\/50{background-color:color-mix(in oklab, var(--color-black) 50%, transparent)}}.bg-blue-500{background-color:var(--color-blue-500)}.bg-current{background-color:currentColor}.bg-cyan-50{background-color:var(--color-cyan-50)}.bg-cyan-100\/40{background-color:#cefafe66}@supports (color:color-mix(in lab, red, red)){.bg-cyan-100\/40{background-color:color-mix(in oklab, var(--color-cyan-100) 40%, transparent)}}.bg-cyan-500{background-color:var(--color-cyan-500)}.bg-gray-700{background-color:var(--color-gray-700)}.bg-green-500{background-color:var(--color-green-500)}.bg-orange-50{background-color:var(--color-orange-50)}.bg-red-500{background-color:var(--color-red-500)}.bg-slate-50{background-color:var(--color-slate-50)}.bg-slate-100{background-color:var(--color-slate-100)}.bg-slate-200{background-color:var(--color-slate-200)}.bg-slate-400\/20{background-color:#90a1b933}@supports (color:color-mix(in lab, red, red)){.bg-slate-400\/20{background-color:color-mix(in oklab, var(--color-slate-400) 20%, transparent)}}.bg-slate-500{background-color:var(--color-slate-500)}.bg-slate-700{background-color:var(--color-slate-700)}.bg-slate-700\/40{background-color:#31415866}@supports (color:color-mix(in lab, red, red)){.bg-slate-700\/40{background-color:color-mix(in oklab, var(--color-slate-700) 40%, transparent)}}.bg-slate-800\/60{background-color:#1d293d99}@supports (color:color-mix(in lab, red, red)){.bg-slate-800\/60{background-color:color-mix(in oklab, var(--color-slate-800) 60%, transparent)}}.bg-slate-900\/35{background-color:#0f172b59}@supports (color:color-mix(in lab, red, red)){.bg-slate-900\/35{background-color:color-mix(in oklab, var(--color-slate-900) 35%, transparent)}}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.bg-white\/60{background-color:#fff9}@supports (color:color-mix(in lab, red, red)){.bg-white\/60{background-color:color-mix(in oklab, var(--color-white) 60%, transparent)}}.bg-white\/80{background-color:#fffc}@supports (color:color-mix(in lab, red, red)){.bg-white\/80{background-color:color-mix(in oklab, var(--color-white) 80%, transparent)}}.bg-yellow-400{background-color:var(--color-yellow-400)}.bg-yellow-500{background-color:var(--color-yellow-500)}.bg-linear-to-br{--tw-gradient-position:to bottom right}@supports (background-image:linear-gradient(in lab, red, red)){.bg-linear-to-br{--tw-gradient-position:to bottom right in oklab}}.bg-linear-to-br{background-image:linear-gradient(var(--tw-gradient-stops))}.bg-linear-to-r{--tw-gradient-position:to right}@supports (background-image:linear-gradient(in lab, red, red)){.bg-linear-to-r{--tw-gradient-position:to right in oklab}}.bg-linear-to-r{background-image:linear-gradient(var(--tw-gradient-stops))}.bg-gradient-to-r{--tw-gradient-position:to right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.from-cyan-50{--tw-gradient-from:var(--color-cyan-50);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.from-emerald-50{--tw-gradient-from:var(--color-emerald-50);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.from-green-500{--tw-gradient-from:var(--color-green-500);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.from-red-500{--tw-gradient-from:var(--color-red-500);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.from-yellow-400{--tw-gradient-from:var(--color-yellow-400);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.from-0\%{--tw-gradient-from-position:0%}.via-amber-400{--tw-gradient-via:var(--color-amber-400);--tw-gradient-via-stops:var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.via-cyan-500{--tw-gradient-via:var(--color-cyan-500);--tw-gradient-via-stops:var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.via-lime-400{--tw-gradient-via:var(--color-lime-400);--tw-gradient-via-stops:var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.via-purple-500{--tw-gradient-via:var(--color-purple-500);--tw-gradient-via-stops:var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.via-sky-400{--tw-gradient-via:var(--color-sky-400);--tw-gradient-via-stops:var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.via-yellow-400{--tw-gradient-via:var(--color-yellow-400);--tw-gradient-via-stops:var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.to-blue-500{--tw-gradient-to:var(--color-blue-500);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.to-green-500{--tw-gradient-to:var(--color-green-500);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.to-white{--tw-gradient-to:var(--color-white);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.to-50\%{--tw-gradient-to-position:50%}.\!p-0{padding:calc(var(--spacing) * 0)!important}.p-0{padding:calc(var(--spacing) * 0)}.p-0\!{padding:calc(var(--spacing) * 0)!important}.p-1{padding:calc(var(--spacing) * 1)}.p-1\.5{padding:calc(var(--spacing) * 1.5)}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-6{padding:calc(var(--spacing) * 6)}.p-10{padding:calc(var(--spacing) * 10)}.px-1{padding-inline:calc(var(--spacing) * 1)}.px-1\!{padding-inline:calc(var(--spacing) * 1)!important}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\!{padding-inline:calc(var(--spacing) * 2)!important}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-3\.5{padding-inline:calc(var(--spacing) * 3.5)}.px-4{padding-inline:calc(var(--spacing) * 4)}.py-0{padding-block:calc(var(--spacing) * 0)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-1\!{padding-block:calc(var(--spacing) * 1)!important}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\!{padding-block:calc(var(--spacing) * 2)!important}.py-3{padding-block:calc(var(--spacing) * 3)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-8{padding-block:calc(var(--spacing) * 8)}.ps-3{padding-inline-start:calc(var(--spacing) * 3)}.pt-1{padding-top:calc(var(--spacing) * 1)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-3{padding-top:calc(var(--spacing) * 3)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pb-1{padding-bottom:calc(var(--spacing) * 1)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pl-2{padding-left:calc(var(--spacing) * 2)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.text-start{text-align:start}.align-middle{vertical-align:middle}.font-mono{font-family:var(--font-mono)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[0\.8rem\]{font-size:.8rem}.text-\[0\.65rem\]{font-size:.65rem}.text-\[0\.85rem\]{font-size:.85rem}.text-\[0\.95rem\]{font-size:.95rem}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.tracking-widest{--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest)}.text-balance{text-wrap:balance}.text-nowrap{text-wrap:nowrap}.wrap-anywhere{overflow-wrap:anywhere}.whitespace-nowrap{white-space:nowrap}.text-amber-400{color:var(--color-amber-400)}.text-amber-600\/80{color:#dd7400cc}@supports (color:color-mix(in lab, red, red)){.text-amber-600\/80{color:color-mix(in oklab, var(--color-amber-600) 80%, transparent)}}.text-amber-700{color:var(--color-amber-700)}.text-blue-500{color:var(--color-blue-500)}.text-cyan-700{color:var(--color-cyan-700)}.text-cyan-900{color:var(--color-cyan-900)}.text-emerald-500{color:var(--color-emerald-500)}.text-emerald-700{color:var(--color-emerald-700)}.text-gray-100{color:var(--color-gray-100)}.text-gray-900{color:var(--color-gray-900)}.text-green-500{color:var(--color-green-500)}.text-inherit{color:inherit}.text-inherit\!{color:inherit!important}.text-orange-500{color:var(--color-orange-500)}.text-orange-600{color:var(--color-orange-600)}.text-orange-700{color:var(--color-orange-700)}.text-red-400{color:var(--color-red-400)}.text-red-500{color:var(--color-red-500)}.text-slate-100\/95{color:#f1f5f9f2}@supports (color:color-mix(in lab, red, red)){.text-slate-100\/95{color:color-mix(in oklab, var(--color-slate-100) 95%, transparent)}}.text-slate-200{color:var(--color-slate-200)}.text-slate-300{color:var(--color-slate-300)}.text-slate-400{color:var(--color-slate-400)}.text-slate-400\/90{color:#90a1b9e6}@supports (color:color-mix(in lab, red, red)){.text-slate-400\/90{color:color-mix(in oklab, var(--color-slate-400) 90%, transparent)}}.text-slate-500{color:var(--color-slate-500)}.text-slate-600{color:var(--color-slate-600)}.text-slate-700{color:var(--color-slate-700)}.text-slate-800{color:var(--color-slate-800)}.text-slate-900{color:var(--color-slate-900)}.text-slate-900\/70{color:#0f172bb3}@supports (color:color-mix(in lab, red, red)){.text-slate-900\/70{color:color-mix(in oklab, var(--color-slate-900) 70%, transparent)}}.text-slate-900\/85{color:#0f172bd9}@supports (color:color-mix(in lab, red, red)){.text-slate-900\/85{color:color-mix(in oklab, var(--color-slate-900) 85%, transparent)}}.text-slate-900\/90{color:#0f172be6}@supports (color:color-mix(in lab, red, red)){.text-slate-900\/90{color:color-mix(in oklab, var(--color-slate-900) 90%, transparent)}}.text-white{color:var(--color-white)}.text-yellow-500{color:var(--color-yellow-500)}.uppercase{text-transform:uppercase}.ordinal{--tw-ordinal:ordinal;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.placeholder-slate-400::placeholder{color:var(--color-slate-400)}.opacity-0{opacity:0}.opacity-25{opacity:.25}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-75{opacity:.75}.opacity-90{opacity:.9}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_0_8px_rgba\(34\,197\,94\,0\.6\)\]{--tw-shadow:0 0 8px var(--tw-shadow-color,#22c55e99);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-blue-500\/50{--tw-shadow-color:#3080ff80}@supports (color:color-mix(in lab, red, red)){.shadow-blue-500\/50{--tw-shadow-color:color-mix(in oklab, color-mix(in oklab, var(--color-blue-500) 50%, transparent) var(--tw-shadow-alpha), transparent)}}.shadow-green-500\/50{--tw-shadow-color:#00c75880}@supports (color:color-mix(in lab, red, red)){.shadow-green-500\/50{--tw-shadow-color:color-mix(in oklab, color-mix(in oklab, var(--color-green-500) 50%, transparent) var(--tw-shadow-alpha), transparent)}}.shadow-orange-400\/40{--tw-shadow-color:#ff8b1a66}@supports (color:color-mix(in lab, red, red)){.shadow-orange-400\/40{--tw-shadow-color:color-mix(in oklab, color-mix(in oklab, var(--color-orange-400) 40%, transparent) var(--tw-shadow-alpha), transparent)}}.shadow-red-500\/50{--tw-shadow-color:#fb2c3680}@supports (color:color-mix(in lab, red, red)){.shadow-red-500\/50{--tw-shadow-color:color-mix(in oklab, color-mix(in oklab, var(--color-red-500) 50%, transparent) var(--tw-shadow-alpha), transparent)}}.shadow-yellow-500\/50{--tw-shadow-color:#edb20080}@supports (color:color-mix(in lab, red, red)){.shadow-yellow-500\/50{--tw-shadow-color:color-mix(in oklab, color-mix(in oklab, var(--color-yellow-500) 50%, transparent) var(--tw-shadow-alpha), transparent)}}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.backdrop-blur-sm{--tw-backdrop-blur:blur(var(--blur-sm));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.duration-400{--tw-duration:.4s;transition-duration:.4s}.duration-500{--tw-duration:.5s;transition-duration:.5s}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.\[assembly\:InternalsVisibleTo\(\"axopen\.inspectors_tests\"\)\]{assembly:InternalsVisibleTo("axopen.inspectors tests")}.\[assembly\:InternalsVisibleTo\(\"axopen_core_tests\"\)\]{assembly:InternalsVisibleTo("axopen core tests")}.\[assembly\:InternalsVisibleTo\(\"axopen_core_tests_L1\"\)\]{assembly:InternalsVisibleTo("axopen core tests L1")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentsabbrobotics_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentsabbrobotics tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentsballuffidentification_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentsballuffidentification tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentscognexvision_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentscognexvision tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentsdesouttertightening_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentsdesouttertightening tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentsdrives_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentsdrives tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentsfestodrives_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentsfestodrives tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentskeyencevision_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentskeyencevision tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentskukarobotics_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentskukarobotics tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentsmitsubishirobotics_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentsmitsubishirobotics tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentsrexrothdrives_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentsrexrothdrives tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentsrexrothpress_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentsrexrothpress tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentsrobotics_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentsrobotics tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentssiemidentification_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentssiemidentification tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentsurrobotics_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentsurrobotics tests")}.\[assembly\:InternalsVisibleTo\(\"axopenio_tests\"\)\]{assembly:InternalsVisibleTo("axopenio tests")}.\[assembly\:InternalsVisibleTo\(\"components\.dukane\.welders_tests\"\)\]{assembly:InternalsVisibleTo("components.dukane.welders tests")}.\[assembly\:InternalsVisibleTo\(\"components\.rexroth\.tightening_tests\"\)\]{assembly:InternalsVisibleTo("components.rexroth.tightening tests")}.\[assembly\:InternalsVisibleTo\(\"components\.siem\.communication_tests\"\)\]{assembly:InternalsVisibleTo("components.siem.communication tests")}.\[assembly\:InternalsVisibleTo\(\"components\.zebra\.vision_tests\"\)\]{assembly:InternalsVisibleTo("components.zebra.vision tests")}.\[assembly\:InternalsVisibleTo\(\"elementscomponents_tests\"\)\]{assembly:InternalsVisibleTo("elementscomponents tests")}.\[assembly\:InternalsVisibleTo\(\"librarytemplate_tests\"\)\]{assembly:InternalsVisibleTo("librarytemplate tests")}.\[assembly\:InternalsVisibleTo\(\"pneumaticcomponents_tests\"\)\]{assembly:InternalsVisibleTo("pneumaticcomponents tests")}@media (hover:hover){.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}.hover\:-translate-y-0\.5:hover{--tw-translate-y:calc(var(--spacing) * -.5);translate:var(--tw-translate-x) var(--tw-translate-y)}.hover\:border-slate-300:hover{border-color:var(--color-slate-300)}.hover\:bg-slate-50:hover{background-color:var(--color-slate-50)}.hover\:bg-slate-600:hover{background-color:var(--color-slate-600)}.hover\:text-slate-700:hover{color:var(--color-slate-700)}.hover\:text-slate-800:hover{color:var(--color-slate-800)}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-100:hover{opacity:1}.hover\:shadow-lg:hover{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}}.focus\:border-cyan-500:focus{border-color:var(--color-cyan-500)}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus\:ring-cyan-200:focus{--tw-ring-color:var(--color-cyan-200)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}@media (min-width:40rem){.sm\:inline{display:inline}.sm\:px-6{padding-inline:calc(var(--spacing) * 6)}}@media (min-width:48rem){.md\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:grid-rows-2{grid-template-rows:repeat(2,minmax(0,1fr))}.md\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}@media (min-width:64rem){.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.lg\:flex-row{flex-direction:row}.lg\:items-center{align-items:center}.lg\:justify-between{justify-content:space-between}.lg\:px-8{padding-inline:calc(var(--spacing) * 8)}}@media (min-width:80rem){.xl\:col-span-1{grid-column:span 1/span 1}.xl\:col-span-2{grid-column:span 2/span 2}.xl\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-space-x-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"";inherits:false;initial-value:100%}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}@keyframes bounce{0%,to{animation-timing-function:cubic-bezier(.8,0,1,1);transform:translateY(-25%)}50%{animation-timing-function:cubic-bezier(0,0,.2,1);transform:none}} \ No newline at end of file